diff options
| author | julian laplace <julescarbon@gmail.com> | 2023-05-09 22:56:52 +0200 |
|---|---|---|
| committer | julian laplace <julescarbon@gmail.com> | 2023-05-09 22:56:52 +0200 |
| commit | db7917f9f10b442b98d6cfc8e9231e1f66f1dd75 (patch) | |
| tree | e30bb0b37a955008a6077923496ee30486099111 /dist | |
| parent | 8c19ceb702ebf1fdd66d1c71e491a21974e9c638 (diff) | |
build
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 228e779..71293a0 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")},905:(__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);\nvar react_namespaceObject = /*#__PURE__*/__webpack_require__.t(react, 2);\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 device";\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: "\'Menlo\', monospace",\n borderRadius: "3px",\n transform: "translate3D(-50%,-50%,0)",\n textAlign: "center",\n lineHeight: "1.5",\n width: "150px",\n cursor: "pointer"\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.filter(function (value) {\n return value && value[0] < time;\n }).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 = 1.1;\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_SHAPES = {\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 shape: "triangle",\n frequency: randrange(0.5, 1.5)\n }, {\n shape: "triangle",\n frequency: randrange(0.75, 2.25)\n }, {\n shape: "triangle",\n frequency: randrange(1, 3)\n }, {\n shape: "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_SHAPES[wave.shape](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: ./node_modules/@babel/runtime/helpers/esm/typeof.js\nfunction typeof_typeof(obj) {\n "@babel/helpers - typeof";\n\n return typeof_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 }, typeof_typeof(obj);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPrimitive.js\n\nfunction toPrimitive_toPrimitive(input, hint) {\n if (typeof_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_typeof(res) !== "object") return res;\n throw new TypeError("@@toPrimitive must return a primitive value.");\n }\n return (hint === "string" ? String : Number)(input);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPropertyKey.js\n\n\nfunction toPropertyKey_toPropertyKey(arg) {\n var key = toPrimitive_toPrimitive(arg, "string");\n return typeof_typeof(key) === "symbol" ? key : String(key);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey_toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js\nfunction arrayLikeToArray_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray_arrayLikeToArray(arr);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\n\nfunction unsupportedIterableToArray_unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return arrayLikeToArray_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_arrayLikeToArray(o, minLen);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js\nfunction _nonIterableSpread() {\n throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js\n\n\n\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || unsupportedIterableToArray_unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nfunction arrayWithHoles_arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction iterableToArrayLimit_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nfunction nonIterableRest_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction slicedToArray_slicedToArray(arr, i) {\n return arrayWithHoles_arrayWithHoles(arr) || iterableToArrayLimit_iterableToArrayLimit(arr, i) || unsupportedIterableToArray_unsupportedIterableToArray(arr, i) || nonIterableRest_nonIterableRest();\n}\n// EXTERNAL MODULE: ./node_modules/classnames/index.js\nvar classnames = __webpack_require__(184);\nvar classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/warning.js\n/* eslint-disable no-console */\nvar warned = {};\nvar preWarningFns = [];\n\n/**\n * Pre warning enable you to parse content before console.error.\n * Modify to null will prevent warning.\n */\nvar preMessage = function preMessage(fn) {\n preWarningFns.push(fn);\n};\nfunction warning(valid, message) {\n // Support uglify\n if (false) { var finalMessage; }\n}\nfunction note(valid, message) {\n // Support uglify\n if (false) { var finalMessage; }\n}\nfunction resetWarned() {\n warned = {};\n}\nfunction call(method, valid, message) {\n if (!valid && !warned[message]) {\n method(false, message);\n warned[message] = true;\n }\n}\nfunction warningOnce(valid, message) {\n call(warning, valid, message);\n}\nfunction noteOnce(valid, message) {\n call(note, valid, message);\n}\nwarningOnce.preMessage = preMessage;\nwarningOnce.resetWarned = resetWarned;\nwarningOnce.noteOnce = noteOnce;\n/* harmony default export */ const es_warning = (warningOnce);\n/* eslint-enable */\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/isEqual.js\n\n\n\n/**\n * Deeply compares two object literals.\n * @param obj1 object 1\n * @param obj2 object 2\n * @param shallow shallow compare\n * @returns\n */\nfunction isEqual(obj1, obj2) {\n var shallow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n // https://github.com/mapbox/mapbox-gl-js/pull/5979/files#diff-fde7145050c47cc3a306856efd5f9c3016e86e859de9afbd02c879be5067e58f\n var refSet = new Set();\n function deepEqual(a, b) {\n var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var circular = refSet.has(a);\n es_warning(!circular, \'Warning: There may be circular references\');\n if (circular) {\n return false;\n }\n if (a === b) {\n return true;\n }\n if (shallow && level > 1) {\n return false;\n }\n refSet.add(a);\n var newLevel = level + 1;\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i], newLevel)) {\n return false;\n }\n }\n return true;\n }\n if (a && b && typeof_typeof(a) === \'object\' && typeof_typeof(b) === \'object\') {\n var keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) {\n return false;\n }\n return keys.every(function (key) {\n return deepEqual(a[key], b[key], newLevel);\n });\n }\n // other\n return false;\n }\n return deepEqual(obj1, obj2);\n}\n/* harmony default export */ const es_isEqual = (isEqual);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useEvent.js\n\nfunction useEvent(callback) {\n var fnRef = react.useRef();\n fnRef.current = callback;\n var memoFn = react.useCallback(function () {\n var _fnRef$current;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return (_fnRef$current = fnRef.current) === null || _fnRef$current === void 0 ? void 0 : _fnRef$current.call.apply(_fnRef$current, [fnRef].concat(args));\n }, []);\n return memoFn;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/canUseDom.js\nfunction canUseDom() {\n return !!(typeof window !== \'undefined\' && window.document && window.document.createElement);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useLayoutEffect.js\n\n\n\n/**\n * Wrap `React.useLayoutEffect` which will not throw warning message in test env\n */\nvar useLayoutEffect = true && canUseDom() ? react.useLayoutEffect : react.useEffect;\n/* harmony default export */ const hooks_useLayoutEffect = (useLayoutEffect);\nvar useLayoutUpdateEffect = function useLayoutUpdateEffect(callback, deps) {\n var firstMountRef = react.useRef(true);\n useLayoutEffect(function () {\n if (!firstMountRef.current) {\n return callback();\n }\n }, deps);\n\n // We tell react that first mount has passed\n useLayoutEffect(function () {\n firstMountRef.current = false;\n return function () {\n firstMountRef.current = true;\n };\n }, []);\n};\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useState.js\n\n\n/**\n * Same as React.useState but `setState` accept `ignoreDestroy` param to not to setState after destroyed.\n * We do not make this auto is to avoid real memory leak.\n * Developer should confirm it\'s safe to ignore themselves.\n */\nfunction useSafeState(defaultValue) {\n var destroyRef = react.useRef(false);\n var _React$useState = react.useState(defaultValue),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n value = _React$useState2[0],\n setValue = _React$useState2[1];\n react.useEffect(function () {\n destroyRef.current = false;\n return function () {\n destroyRef.current = true;\n };\n }, []);\n function safeSetState(updater, ignoreDestroy) {\n if (ignoreDestroy && destroyRef.current) {\n return;\n }\n setValue(updater);\n }\n return [value, safeSetState];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useMergedState.js\n\n\n\n\n/** We only think `undefined` is empty */\nfunction hasValue(value) {\n return value !== undefined;\n}\n\n/**\n * Similar to `useState` but will use props value if provided.\n * Note that internal use rc-util `useState` hook.\n */\nfunction useMergedState(defaultStateValue, option) {\n var _ref = option || {},\n defaultValue = _ref.defaultValue,\n value = _ref.value,\n onChange = _ref.onChange,\n postState = _ref.postState;\n\n // ======================= Init =======================\n var _useState = useSafeState(function () {\n if (hasValue(value)) {\n return value;\n } else if (hasValue(defaultValue)) {\n return typeof defaultValue === \'function\' ? defaultValue() : defaultValue;\n } else {\n return typeof defaultStateValue === \'function\' ? defaultStateValue() : defaultStateValue;\n }\n }),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n innerValue = _useState2[0],\n setInnerValue = _useState2[1];\n var mergedValue = value !== undefined ? value : innerValue;\n var postMergedValue = postState ? postState(mergedValue) : mergedValue;\n\n // ====================== Change ======================\n var onChangeFn = useEvent(onChange);\n var _useState3 = useSafeState([mergedValue]),\n _useState4 = slicedToArray_slicedToArray(_useState3, 2),\n prevValue = _useState4[0],\n setPrevValue = _useState4[1];\n useLayoutUpdateEffect(function () {\n var prev = prevValue[0];\n if (innerValue !== prev) {\n onChangeFn(innerValue, prev);\n }\n }, [prevValue]);\n\n // Sync value back to `undefined` when it from control to un-control\n useLayoutUpdateEffect(function () {\n if (!hasValue(value)) {\n setInnerValue(value);\n }\n }, [value]);\n\n // ====================== Update ======================\n var triggerChange = useEvent(function (updater, ignoreDestroy) {\n setInnerValue(updater, ignoreDestroy);\n setPrevValue([mergedValue], ignoreDestroy);\n });\n return [postMergedValue, triggerChange];\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js\nfunction extends_extends() {\n extends_extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return extends_extends.apply(this, arguments);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js\n\nfunction objectWithoutProperties_objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = _objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectSpread2.js\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n return keys;\n}\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/KeyCode.js\n/**\n * @ignore\n * some key-codes definition and utils from closure-library\n * @author yiminghe@gmail.com\n */\n\nvar KeyCode = {\n /**\n * MAC_ENTER\n */\n MAC_ENTER: 3,\n /**\n * BACKSPACE\n */\n BACKSPACE: 8,\n /**\n * TAB\n */\n TAB: 9,\n /**\n * NUMLOCK on FF/Safari Mac\n */\n NUM_CENTER: 12,\n // NUMLOCK on FF/Safari Mac\n /**\n * ENTER\n */\n ENTER: 13,\n /**\n * SHIFT\n */\n SHIFT: 16,\n /**\n * CTRL\n */\n CTRL: 17,\n /**\n * ALT\n */\n ALT: 18,\n /**\n * PAUSE\n */\n PAUSE: 19,\n /**\n * CAPS_LOCK\n */\n CAPS_LOCK: 20,\n /**\n * ESC\n */\n ESC: 27,\n /**\n * SPACE\n */\n SPACE: 32,\n /**\n * PAGE_UP\n */\n PAGE_UP: 33,\n // also NUM_NORTH_EAST\n /**\n * PAGE_DOWN\n */\n PAGE_DOWN: 34,\n // also NUM_SOUTH_EAST\n /**\n * END\n */\n END: 35,\n // also NUM_SOUTH_WEST\n /**\n * HOME\n */\n HOME: 36,\n // also NUM_NORTH_WEST\n /**\n * LEFT\n */\n LEFT: 37,\n // also NUM_WEST\n /**\n * UP\n */\n UP: 38,\n // also NUM_NORTH\n /**\n * RIGHT\n */\n RIGHT: 39,\n // also NUM_EAST\n /**\n * DOWN\n */\n DOWN: 40,\n // also NUM_SOUTH\n /**\n * PRINT_SCREEN\n */\n PRINT_SCREEN: 44,\n /**\n * INSERT\n */\n INSERT: 45,\n // also NUM_INSERT\n /**\n * DELETE\n */\n DELETE: 46,\n // also NUM_DELETE\n /**\n * ZERO\n */\n ZERO: 48,\n /**\n * ONE\n */\n ONE: 49,\n /**\n * TWO\n */\n TWO: 50,\n /**\n * THREE\n */\n THREE: 51,\n /**\n * FOUR\n */\n FOUR: 52,\n /**\n * FIVE\n */\n FIVE: 53,\n /**\n * SIX\n */\n SIX: 54,\n /**\n * SEVEN\n */\n SEVEN: 55,\n /**\n * EIGHT\n */\n EIGHT: 56,\n /**\n * NINE\n */\n NINE: 57,\n /**\n * QUESTION_MARK\n */\n QUESTION_MARK: 63,\n // needs localization\n /**\n * A\n */\n A: 65,\n /**\n * B\n */\n B: 66,\n /**\n * C\n */\n C: 67,\n /**\n * D\n */\n D: 68,\n /**\n * E\n */\n E: 69,\n /**\n * F\n */\n F: 70,\n /**\n * G\n */\n G: 71,\n /**\n * H\n */\n H: 72,\n /**\n * I\n */\n I: 73,\n /**\n * J\n */\n J: 74,\n /**\n * K\n */\n K: 75,\n /**\n * L\n */\n L: 76,\n /**\n * M\n */\n M: 77,\n /**\n * N\n */\n N: 78,\n /**\n * O\n */\n O: 79,\n /**\n * P\n */\n P: 80,\n /**\n * Q\n */\n Q: 81,\n /**\n * R\n */\n R: 82,\n /**\n * S\n */\n S: 83,\n /**\n * T\n */\n T: 84,\n /**\n * U\n */\n U: 85,\n /**\n * V\n */\n V: 86,\n /**\n * W\n */\n W: 87,\n /**\n * X\n */\n X: 88,\n /**\n * Y\n */\n Y: 89,\n /**\n * Z\n */\n Z: 90,\n /**\n * META\n */\n META: 91,\n // WIN_KEY_LEFT\n /**\n * WIN_KEY_RIGHT\n */\n WIN_KEY_RIGHT: 92,\n /**\n * CONTEXT_MENU\n */\n CONTEXT_MENU: 93,\n /**\n * NUM_ZERO\n */\n NUM_ZERO: 96,\n /**\n * NUM_ONE\n */\n NUM_ONE: 97,\n /**\n * NUM_TWO\n */\n NUM_TWO: 98,\n /**\n * NUM_THREE\n */\n NUM_THREE: 99,\n /**\n * NUM_FOUR\n */\n NUM_FOUR: 100,\n /**\n * NUM_FIVE\n */\n NUM_FIVE: 101,\n /**\n * NUM_SIX\n */\n NUM_SIX: 102,\n /**\n * NUM_SEVEN\n */\n NUM_SEVEN: 103,\n /**\n * NUM_EIGHT\n */\n NUM_EIGHT: 104,\n /**\n * NUM_NINE\n */\n NUM_NINE: 105,\n /**\n * NUM_MULTIPLY\n */\n NUM_MULTIPLY: 106,\n /**\n * NUM_PLUS\n */\n NUM_PLUS: 107,\n /**\n * NUM_MINUS\n */\n NUM_MINUS: 109,\n /**\n * NUM_PERIOD\n */\n NUM_PERIOD: 110,\n /**\n * NUM_DIVISION\n */\n NUM_DIVISION: 111,\n /**\n * F1\n */\n F1: 112,\n /**\n * F2\n */\n F2: 113,\n /**\n * F3\n */\n F3: 114,\n /**\n * F4\n */\n F4: 115,\n /**\n * F5\n */\n F5: 116,\n /**\n * F6\n */\n F6: 117,\n /**\n * F7\n */\n F7: 118,\n /**\n * F8\n */\n F8: 119,\n /**\n * F9\n */\n F9: 120,\n /**\n * F10\n */\n F10: 121,\n /**\n * F11\n */\n F11: 122,\n /**\n * F12\n */\n F12: 123,\n /**\n * NUMLOCK\n */\n NUMLOCK: 144,\n /**\n * SEMICOLON\n */\n SEMICOLON: 186,\n // needs localization\n /**\n * DASH\n */\n DASH: 189,\n // needs localization\n /**\n * EQUALS\n */\n EQUALS: 187,\n // needs localization\n /**\n * COMMA\n */\n COMMA: 188,\n // needs localization\n /**\n * PERIOD\n */\n PERIOD: 190,\n // needs localization\n /**\n * SLASH\n */\n SLASH: 191,\n // needs localization\n /**\n * APOSTROPHE\n */\n APOSTROPHE: 192,\n // needs localization\n /**\n * SINGLE_QUOTE\n */\n SINGLE_QUOTE: 222,\n // needs localization\n /**\n * OPEN_SQUARE_BRACKET\n */\n OPEN_SQUARE_BRACKET: 219,\n // needs localization\n /**\n * BACKSLASH\n */\n BACKSLASH: 220,\n // needs localization\n /**\n * CLOSE_SQUARE_BRACKET\n */\n CLOSE_SQUARE_BRACKET: 221,\n // needs localization\n /**\n * WIN_KEY\n */\n WIN_KEY: 224,\n /**\n * MAC_FF_META\n */\n MAC_FF_META: 224,\n // Firefox (Gecko) fires this for the meta key instead of 91\n /**\n * WIN_IME\n */\n WIN_IME: 229,\n // ======================== Function ========================\n /**\n * whether text and modified key is entered at the same time.\n */\n isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e) {\n var keyCode = e.keyCode;\n if (e.altKey && !e.ctrlKey || e.metaKey ||\n // Function keys don\'t generate text\n keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12) {\n return false;\n }\n\n // The following keys are quite harmless, even in combination with\n // CTRL, ALT or SHIFT.\n switch (keyCode) {\n case KeyCode.ALT:\n case KeyCode.CAPS_LOCK:\n case KeyCode.CONTEXT_MENU:\n case KeyCode.CTRL:\n case KeyCode.DOWN:\n case KeyCode.END:\n case KeyCode.ESC:\n case KeyCode.HOME:\n case KeyCode.INSERT:\n case KeyCode.LEFT:\n case KeyCode.MAC_FF_META:\n case KeyCode.META:\n case KeyCode.NUMLOCK:\n case KeyCode.NUM_CENTER:\n case KeyCode.PAGE_DOWN:\n case KeyCode.PAGE_UP:\n case KeyCode.PAUSE:\n case KeyCode.PRINT_SCREEN:\n case KeyCode.RIGHT:\n case KeyCode.SHIFT:\n case KeyCode.UP:\n case KeyCode.WIN_KEY:\n case KeyCode.WIN_KEY_RIGHT:\n return false;\n default:\n return true;\n }\n },\n /**\n * whether character is entered.\n */\n isCharacterKey: function isCharacterKey(keyCode) {\n if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {\n return true;\n }\n if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {\n return true;\n }\n if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {\n return true;\n }\n\n // Safari sends zero key code for non-latin characters.\n if (window.navigator.userAgent.indexOf(\'WebKit\') !== -1 && keyCode === 0) {\n return true;\n }\n switch (keyCode) {\n case KeyCode.SPACE:\n case KeyCode.QUESTION_MARK:\n case KeyCode.NUM_PLUS:\n case KeyCode.NUM_MINUS:\n case KeyCode.NUM_PERIOD:\n case KeyCode.NUM_DIVISION:\n case KeyCode.SEMICOLON:\n case KeyCode.DASH:\n case KeyCode.EQUALS:\n case KeyCode.COMMA:\n case KeyCode.PERIOD:\n case KeyCode.SLASH:\n case KeyCode.APOSTROPHE:\n case KeyCode.SINGLE_QUOTE:\n case KeyCode.OPEN_SQUARE_BRACKET:\n case KeyCode.BACKSLASH:\n case KeyCode.CLOSE_SQUARE_BRACKET:\n return true;\n default:\n return false;\n }\n }\n};\n/* harmony default export */ const es_KeyCode = (KeyCode);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/context.js\n\nvar SliderContext = /*#__PURE__*/react.createContext({\n min: 0,\n max: 0,\n direction: \'ltr\',\n step: 1,\n includedStart: 0,\n includedEnd: 0,\n tabIndex: 0,\n keyboard: true\n});\n/* harmony default export */ const es_context = (SliderContext);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/util.js\nfunction getOffset(value, min, max) {\n return (value - min) / (max - min);\n}\nfunction getDirectionStyle(direction, value, min, max) {\n var offset = getOffset(value, min, max);\n var positionStyle = {};\n switch (direction) {\n case \'rtl\':\n positionStyle.right = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateX(50%)\';\n break;\n case \'btt\':\n positionStyle.bottom = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateY(50%)\';\n break;\n case \'ttb\':\n positionStyle.top = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateY(-50%)\';\n break;\n default:\n positionStyle.left = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateX(-50%)\';\n break;\n }\n return positionStyle;\n}\n/** Return index value if is list or return value directly */\nfunction getIndex(value, index) {\n return Array.isArray(value) ? value[index] : value;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Handles/Handle.js\n\n\n\n\nvar _excluded = ["prefixCls", "value", "valueIndex", "onStartMove", "style", "render", "dragging", "onOffsetChange"];\n\n\n\n\n\nvar Handle = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _classNames, _getIndex;\n var prefixCls = props.prefixCls,\n value = props.value,\n valueIndex = props.valueIndex,\n onStartMove = props.onStartMove,\n style = props.style,\n render = props.render,\n dragging = props.dragging,\n onOffsetChange = props.onOffsetChange,\n restProps = objectWithoutProperties_objectWithoutProperties(props, _excluded);\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n disabled = _React$useContext.disabled,\n keyboard = _React$useContext.keyboard,\n range = _React$useContext.range,\n tabIndex = _React$useContext.tabIndex,\n ariaLabelForHandle = _React$useContext.ariaLabelForHandle,\n ariaLabelledByForHandle = _React$useContext.ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle = _React$useContext.ariaValueTextFormatterForHandle;\n var handlePrefixCls = "".concat(prefixCls, "-handle");\n // ============================ Events ============================\n var onInternalStartMove = function onInternalStartMove(e) {\n if (!disabled) {\n onStartMove(e, valueIndex);\n }\n };\n // =========================== Keyboard ===========================\n var onKeyDown = function onKeyDown(e) {\n if (!disabled && keyboard) {\n var offset = null;\n // Change the value\n switch (e.which || e.keyCode) {\n case es_KeyCode.LEFT:\n offset = direction === \'ltr\' || direction === \'btt\' ? -1 : 1;\n break;\n case es_KeyCode.RIGHT:\n offset = direction === \'ltr\' || direction === \'btt\' ? 1 : -1;\n break;\n // Up is plus\n case es_KeyCode.UP:\n offset = direction !== \'ttb\' ? 1 : -1;\n break;\n // Down is minus\n case es_KeyCode.DOWN:\n offset = direction !== \'ttb\' ? -1 : 1;\n break;\n case es_KeyCode.HOME:\n offset = \'min\';\n break;\n case es_KeyCode.END:\n offset = \'max\';\n break;\n case es_KeyCode.PAGE_UP:\n offset = 2;\n break;\n case es_KeyCode.PAGE_DOWN:\n offset = -2;\n break;\n }\n if (offset !== null) {\n e.preventDefault();\n onOffsetChange(offset, valueIndex);\n }\n }\n };\n // ============================ Offset ============================\n var positionStyle = getDirectionStyle(direction, value, min, max);\n // ============================ Render ============================\n var handleNode = /*#__PURE__*/react.createElement("div", extends_extends({\n ref: ref,\n className: classnames_default()(handlePrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(handlePrefixCls, "-").concat(valueIndex + 1), range), _defineProperty(_classNames, "".concat(handlePrefixCls, "-dragging"), dragging), _classNames)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: onInternalStartMove,\n onTouchStart: onInternalStartMove,\n onKeyDown: onKeyDown,\n tabIndex: disabled ? null : getIndex(tabIndex, valueIndex),\n role: "slider",\n "aria-valuemin": min,\n "aria-valuemax": max,\n "aria-valuenow": value,\n "aria-disabled": disabled,\n "aria-label": getIndex(ariaLabelForHandle, valueIndex),\n "aria-labelledby": getIndex(ariaLabelledByForHandle, valueIndex),\n "aria-valuetext": (_getIndex = getIndex(ariaValueTextFormatterForHandle, valueIndex)) === null || _getIndex === void 0 ? void 0 : _getIndex(value)\n }, restProps));\n // Customize\n if (render) {\n handleNode = render(handleNode, {\n index: valueIndex,\n prefixCls: prefixCls,\n value: value,\n dragging: dragging\n });\n }\n return handleNode;\n});\nif (false) {}\n/* harmony default export */ const Handles_Handle = (Handle);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Handles/index.js\n\n\nvar Handles_excluded = ["prefixCls", "style", "onStartMove", "onOffsetChange", "values", "handleRender", "draggingIndex"];\n\n\n\nvar Handles = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var prefixCls = props.prefixCls,\n style = props.style,\n onStartMove = props.onStartMove,\n onOffsetChange = props.onOffsetChange,\n values = props.values,\n handleRender = props.handleRender,\n draggingIndex = props.draggingIndex,\n restProps = objectWithoutProperties_objectWithoutProperties(props, Handles_excluded);\n var handlesRef = react.useRef({});\n react.useImperativeHandle(ref, function () {\n return {\n focus: function focus(index) {\n var _handlesRef$current$i;\n (_handlesRef$current$i = handlesRef.current[index]) === null || _handlesRef$current$i === void 0 ? void 0 : _handlesRef$current$i.focus();\n }\n };\n });\n return /*#__PURE__*/react.createElement(react.Fragment, null, values.map(function (value, index) {\n return /*#__PURE__*/react.createElement(Handles_Handle, extends_extends({\n ref: function ref(node) {\n if (!node) {\n delete handlesRef.current[index];\n } else {\n handlesRef.current[index] = node;\n }\n },\n dragging: draggingIndex === index,\n prefixCls: prefixCls,\n style: getIndex(style, index),\n key: index,\n value: value,\n valueIndex: index,\n onStartMove: onStartMove,\n onOffsetChange: onOffsetChange,\n render: handleRender\n }, restProps));\n }));\n});\nif (false) {}\n/* harmony default export */ const es_Handles = (Handles);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/hooks/useDrag.js\n\n\n\nfunction getPosition(e) {\n var obj = \'touches\' in e ? e.touches[0] : e;\n return {\n pageX: obj.pageX,\n pageY: obj.pageY\n };\n}\nfunction useDrag(containerRef, direction, rawValues, min, max, formatValue, triggerChange, finishChange, offsetValues) {\n var _React$useState = react.useState(null),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n draggingValue = _React$useState2[0],\n setDraggingValue = _React$useState2[1];\n var _React$useState3 = react.useState(-1),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n draggingIndex = _React$useState4[0],\n setDraggingIndex = _React$useState4[1];\n var _React$useState5 = react.useState(rawValues),\n _React$useState6 = slicedToArray_slicedToArray(_React$useState5, 2),\n cacheValues = _React$useState6[0],\n setCacheValues = _React$useState6[1];\n var _React$useState7 = react.useState(rawValues),\n _React$useState8 = slicedToArray_slicedToArray(_React$useState7, 2),\n originValues = _React$useState8[0],\n setOriginValues = _React$useState8[1];\n var mouseMoveEventRef = react.useRef(null);\n var mouseUpEventRef = react.useRef(null);\n react.useEffect(function () {\n if (draggingIndex === -1) {\n setCacheValues(rawValues);\n }\n }, [rawValues, draggingIndex]);\n // Clean up event\n react.useEffect(function () {\n return function () {\n document.removeEventListener(\'mousemove\', mouseMoveEventRef.current);\n document.removeEventListener(\'mouseup\', mouseUpEventRef.current);\n document.removeEventListener(\'touchmove\', mouseMoveEventRef.current);\n document.removeEventListener(\'touchend\', mouseUpEventRef.current);\n };\n }, []);\n var flushValues = function flushValues(nextValues, nextValue) {\n // Perf: Only update state when value changed\n if (cacheValues.some(function (val, i) {\n return val !== nextValues[i];\n })) {\n if (nextValue !== undefined) {\n setDraggingValue(nextValue);\n }\n setCacheValues(nextValues);\n triggerChange(nextValues);\n }\n };\n var updateCacheValue = function updateCacheValue(valueIndex, offsetPercent) {\n // Basic point offset\n if (valueIndex === -1) {\n // >>>> Dragging on the track\n var startValue = originValues[0];\n var endValue = originValues[originValues.length - 1];\n var maxStartOffset = min - startValue;\n var maxEndOffset = max - endValue;\n // Get valid offset\n var offset = offsetPercent * (max - min);\n offset = Math.max(offset, maxStartOffset);\n offset = Math.min(offset, maxEndOffset);\n // Use first value to revert back of valid offset (like steps marks)\n var formatStartValue = formatValue(startValue + offset);\n offset = formatStartValue - startValue;\n var cloneCacheValues = originValues.map(function (val) {\n return val + offset;\n });\n flushValues(cloneCacheValues);\n } else {\n // >>>> Dragging on the handle\n var offsetDist = (max - min) * offsetPercent;\n // Always start with the valueIndex origin value\n var cloneValues = _toConsumableArray(cacheValues);\n cloneValues[valueIndex] = originValues[valueIndex];\n var next = offsetValues(cloneValues, offsetDist, valueIndex, \'dist\');\n flushValues(next.values, next.value);\n }\n };\n // Resolve closure\n var updateCacheValueRef = react.useRef(updateCacheValue);\n updateCacheValueRef.current = updateCacheValue;\n var onStartMove = function onStartMove(e, valueIndex) {\n e.stopPropagation();\n var originValue = rawValues[valueIndex];\n setDraggingIndex(valueIndex);\n setDraggingValue(originValue);\n setOriginValues(rawValues);\n var _getPosition = getPosition(e),\n startX = _getPosition.pageX,\n startY = _getPosition.pageY;\n // Moving\n var onMouseMove = function onMouseMove(event) {\n event.preventDefault();\n var _getPosition2 = getPosition(event),\n moveX = _getPosition2.pageX,\n moveY = _getPosition2.pageY;\n var offsetX = moveX - startX;\n var offsetY = moveY - startY;\n var _containerRef$current = containerRef.current.getBoundingClientRect(),\n width = _containerRef$current.width,\n height = _containerRef$current.height;\n var offSetPercent;\n switch (direction) {\n case \'btt\':\n offSetPercent = -offsetY / height;\n break;\n case \'ttb\':\n offSetPercent = offsetY / height;\n break;\n case \'rtl\':\n offSetPercent = -offsetX / width;\n break;\n default:\n offSetPercent = offsetX / width;\n }\n updateCacheValueRef.current(valueIndex, offSetPercent);\n };\n // End\n var onMouseUp = function onMouseUp(event) {\n event.preventDefault();\n document.removeEventListener(\'mouseup\', onMouseUp);\n document.removeEventListener(\'mousemove\', onMouseMove);\n document.removeEventListener(\'touchend\', onMouseUp);\n document.removeEventListener(\'touchmove\', onMouseMove);\n mouseMoveEventRef.current = null;\n mouseUpEventRef.current = null;\n setDraggingIndex(-1);\n finishChange();\n };\n document.addEventListener(\'mouseup\', onMouseUp);\n document.addEventListener(\'mousemove\', onMouseMove);\n document.addEventListener(\'touchend\', onMouseUp);\n document.addEventListener(\'touchmove\', onMouseMove);\n mouseMoveEventRef.current = onMouseMove;\n mouseUpEventRef.current = onMouseUp;\n };\n // Only return cache value when it mapping with rawValues\n var returnValues = react.useMemo(function () {\n var sourceValues = _toConsumableArray(rawValues).sort(function (a, b) {\n return a - b;\n });\n var targetValues = _toConsumableArray(cacheValues).sort(function (a, b) {\n return a - b;\n });\n return sourceValues.every(function (val, index) {\n return val === targetValues[index];\n }) ? cacheValues : rawValues;\n }, [rawValues, cacheValues]);\n return [draggingIndex, draggingValue, returnValues, onStartMove];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Tracks/Track.js\n\n\n\n\n\nfunction Track(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n start = props.start,\n end = props.end,\n index = props.index,\n onStartMove = props.onStartMove;\n var _React$useContext = react.useContext(es_context),\n direction = _React$useContext.direction,\n min = _React$useContext.min,\n max = _React$useContext.max,\n disabled = _React$useContext.disabled,\n range = _React$useContext.range;\n var trackPrefixCls = "".concat(prefixCls, "-track");\n var offsetStart = getOffset(start, min, max);\n var offsetEnd = getOffset(end, min, max);\n // ============================ Events ============================\n var onInternalStartMove = function onInternalStartMove(e) {\n if (!disabled && onStartMove) {\n onStartMove(e, -1);\n }\n };\n // ============================ Render ============================\n var positionStyle = {};\n switch (direction) {\n case \'rtl\':\n positionStyle.right = "".concat(offsetStart * 100, "%");\n positionStyle.width = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n case \'btt\':\n positionStyle.bottom = "".concat(offsetStart * 100, "%");\n positionStyle.height = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n case \'ttb\':\n positionStyle.top = "".concat(offsetStart * 100, "%");\n positionStyle.height = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n default:\n positionStyle.left = "".concat(offsetStart * 100, "%");\n positionStyle.width = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n }\n return /*#__PURE__*/react.createElement("div", {\n className: classnames_default()(trackPrefixCls, range && "".concat(trackPrefixCls, "-").concat(index + 1)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: onInternalStartMove,\n onTouchStart: onInternalStartMove\n });\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Tracks/index.js\n\n\n\n\nfunction Tracks(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n values = props.values,\n startPoint = props.startPoint,\n onStartMove = props.onStartMove;\n var _React$useContext = react.useContext(es_context),\n included = _React$useContext.included,\n range = _React$useContext.range,\n min = _React$useContext.min;\n var trackList = react.useMemo(function () {\n if (!range) {\n // null value do not have track\n if (values.length === 0) {\n return [];\n }\n var startValue = startPoint !== null && startPoint !== void 0 ? startPoint : min;\n var endValue = values[0];\n return [{\n start: Math.min(startValue, endValue),\n end: Math.max(startValue, endValue)\n }];\n }\n // Multiple\n var list = [];\n for (var i = 0; i < values.length - 1; i += 1) {\n list.push({\n start: values[i],\n end: values[i + 1]\n });\n }\n return list;\n }, [values, range, startPoint, min]);\n return included ? trackList.map(function (_ref, index) {\n var start = _ref.start,\n end = _ref.end;\n return /*#__PURE__*/react.createElement(Track, {\n index: index,\n prefixCls: prefixCls,\n style: getIndex(style, index),\n start: start,\n end: end,\n key: index,\n onStartMove: onStartMove\n });\n }) : null;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Marks/Mark.js\n\n\n\n\n\n\nfunction Mark(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n children = props.children,\n value = props.value,\n _onClick = props.onClick;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n includedStart = _React$useContext.includedStart,\n includedEnd = _React$useContext.includedEnd,\n included = _React$useContext.included;\n var textCls = "".concat(prefixCls, "-text");\n // ============================ Offset ============================\n var positionStyle = getDirectionStyle(direction, value, min, max);\n return /*#__PURE__*/react.createElement("span", {\n className: classnames_default()(textCls, _defineProperty({}, "".concat(textCls, "-active"), included && includedStart <= value && value <= includedEnd)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: function onMouseDown(e) {\n e.stopPropagation();\n },\n onClick: function onClick() {\n _onClick(value);\n }\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Marks/index.js\n\n\nfunction Marks(props) {\n var prefixCls = props.prefixCls,\n marks = props.marks,\n onClick = props.onClick;\n var markPrefixCls = "".concat(prefixCls, "-mark");\n // Not render mark if empty\n if (!marks.length) {\n return null;\n }\n return /*#__PURE__*/react.createElement("div", {\n className: markPrefixCls\n }, marks.map(function (_ref) {\n var value = _ref.value,\n style = _ref.style,\n label = _ref.label;\n return /*#__PURE__*/react.createElement(Mark, {\n key: value,\n prefixCls: markPrefixCls,\n style: style,\n value: value,\n onClick: onClick\n }, label);\n }));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Steps/Dot.js\n\n\n\n\n\n\nfunction Dot(props) {\n var prefixCls = props.prefixCls,\n value = props.value,\n style = props.style,\n activeStyle = props.activeStyle;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n included = _React$useContext.included,\n includedStart = _React$useContext.includedStart,\n includedEnd = _React$useContext.includedEnd;\n var dotClassName = "".concat(prefixCls, "-dot");\n var active = included && includedStart <= value && value <= includedEnd;\n // ============================ Offset ============================\n var mergedStyle = _objectSpread2(_objectSpread2({}, getDirectionStyle(direction, value, min, max)), typeof style === \'function\' ? style(value) : style);\n if (active) {\n mergedStyle = _objectSpread2(_objectSpread2({}, mergedStyle), typeof activeStyle === \'function\' ? activeStyle(value) : activeStyle);\n }\n return /*#__PURE__*/react.createElement("span", {\n className: classnames_default()(dotClassName, _defineProperty({}, "".concat(dotClassName, "-active"), active)),\n style: mergedStyle\n });\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Steps/index.js\n\n\n\nfunction Steps(props) {\n var prefixCls = props.prefixCls,\n marks = props.marks,\n dots = props.dots,\n style = props.style,\n activeStyle = props.activeStyle;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n step = _React$useContext.step;\n var stepDots = react.useMemo(function () {\n var dotSet = new Set();\n // Add marks\n marks.forEach(function (mark) {\n dotSet.add(mark.value);\n });\n // Fill dots\n if (dots && step !== null) {\n var current = min;\n while (current <= max) {\n dotSet.add(current);\n current += step;\n }\n }\n return Array.from(dotSet);\n }, [min, max, step, dots, marks]);\n return /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-step")\n }, stepDots.map(function (dotValue) {\n return /*#__PURE__*/react.createElement(Dot, {\n prefixCls: prefixCls,\n key: dotValue,\n value: dotValue,\n style: style,\n activeStyle: activeStyle\n });\n }));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/hooks/useOffset.js\n\n\nfunction useOffset(min, max, step, markList, allowCross, pushable) {\n var formatRangeValue = react.useCallback(function (val) {\n var formatNextValue = isFinite(val) ? val : min;\n formatNextValue = Math.min(max, val);\n formatNextValue = Math.max(min, formatNextValue);\n return formatNextValue;\n }, [min, max]);\n var formatStepValue = react.useCallback(function (val) {\n if (step !== null) {\n var stepValue = min + Math.round((formatRangeValue(val) - min) / step) * step;\n // Cut number in case to be like 0.30000000000000004\n var getDecimal = function getDecimal(num) {\n return (String(num).split(\'.\')[1] || \'\').length;\n };\n var maxDecimal = Math.max(getDecimal(step), getDecimal(max), getDecimal(min));\n var fixedValue = Number(stepValue.toFixed(maxDecimal));\n return min <= fixedValue && fixedValue <= max ? fixedValue : null;\n }\n return null;\n }, [step, min, max, formatRangeValue]);\n var formatValue = react.useCallback(function (val) {\n var formatNextValue = formatRangeValue(val);\n // List align values\n var alignValues = markList.map(function (mark) {\n return mark.value;\n });\n if (step !== null) {\n alignValues.push(formatStepValue(val));\n }\n // min & max\n alignValues.push(min, max);\n // Align with marks\n var closeValue = alignValues[0];\n var closeDist = max - min;\n alignValues.forEach(function (alignValue) {\n var dist = Math.abs(formatNextValue - alignValue);\n if (dist <= closeDist) {\n closeValue = alignValue;\n closeDist = dist;\n }\n });\n return closeValue;\n }, [min, max, markList, step, formatRangeValue, formatStepValue]);\n // ========================== Offset ==========================\n // Single Value\n var offsetValue = function offsetValue(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n if (typeof offset === \'number\') {\n var nextValue;\n var originValue = values[valueIndex];\n // Only used for `dist` mode\n var targetDistValue = originValue + offset;\n // Compare next step value & mark value which is best match\n var potentialValues = [];\n markList.forEach(function (mark) {\n potentialValues.push(mark.value);\n });\n // Min & Max\n potentialValues.push(min, max);\n // In case origin value is align with mark but not with step\n potentialValues.push(formatStepValue(originValue));\n // Put offset step value also\n var sign = offset > 0 ? 1 : -1;\n if (mode === \'unit\') {\n potentialValues.push(formatStepValue(originValue + sign * step));\n } else {\n potentialValues.push(formatStepValue(targetDistValue));\n }\n // Find close one\n potentialValues = potentialValues.filter(function (val) {\n return val !== null;\n })\n // Remove reverse value\n .filter(function (val) {\n return offset < 0 ? val <= originValue : val >= originValue;\n });\n if (mode === \'unit\') {\n // `unit` mode can not contain itself\n potentialValues = potentialValues.filter(function (val) {\n return val !== originValue;\n });\n }\n var compareValue = mode === \'unit\' ? originValue : targetDistValue;\n nextValue = potentialValues[0];\n var valueDist = Math.abs(nextValue - compareValue);\n potentialValues.forEach(function (potentialValue) {\n var dist = Math.abs(potentialValue - compareValue);\n if (dist < valueDist) {\n nextValue = potentialValue;\n valueDist = dist;\n }\n });\n // Out of range will back to range\n if (nextValue === undefined) {\n return offset < 0 ? min : max;\n }\n // `dist` mode\n if (mode === \'dist\') {\n return nextValue;\n }\n // `unit` mode may need another round\n if (Math.abs(offset) > 1) {\n var cloneValues = _toConsumableArray(values);\n cloneValues[valueIndex] = nextValue;\n return offsetValue(cloneValues, offset - sign, valueIndex, mode);\n }\n return nextValue;\n } else if (offset === \'min\') {\n return min;\n } else if (offset === \'max\') {\n return max;\n }\n };\n /** Same as `offsetValue` but return `changed` mark to tell value changed */\n var offsetChangedValue = function offsetChangedValue(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n var originValue = values[valueIndex];\n var nextValue = offsetValue(values, offset, valueIndex, mode);\n return {\n value: nextValue,\n changed: nextValue !== originValue\n };\n };\n var needPush = function needPush(dist) {\n return pushable === null && dist === 0 || typeof pushable === \'number\' && dist < pushable;\n };\n // Values\n var offsetValues = function offsetValues(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n var nextValues = values.map(formatValue);\n var originValue = nextValues[valueIndex];\n var nextValue = offsetValue(nextValues, offset, valueIndex, mode);\n nextValues[valueIndex] = nextValue;\n if (allowCross === false) {\n // >>>>> Allow Cross\n var pushNum = pushable || 0;\n // ============ AllowCross ===============\n if (valueIndex > 0 && nextValues[valueIndex - 1] !== originValue) {\n nextValues[valueIndex] = Math.max(nextValues[valueIndex], nextValues[valueIndex - 1] + pushNum);\n }\n if (valueIndex < nextValues.length - 1 && nextValues[valueIndex + 1] !== originValue) {\n nextValues[valueIndex] = Math.min(nextValues[valueIndex], nextValues[valueIndex + 1] - pushNum);\n }\n } else if (typeof pushable === \'number\' || pushable === null) {\n // >>>>> Pushable\n // =============== Push ==================\n // >>>>>> Basic push\n // End values\n for (var i = valueIndex + 1; i < nextValues.length; i += 1) {\n var changed = true;\n while (needPush(nextValues[i] - nextValues[i - 1]) && changed) {\n var _offsetChangedValue = offsetChangedValue(nextValues, 1, i);\n nextValues[i] = _offsetChangedValue.value;\n changed = _offsetChangedValue.changed;\n }\n }\n // Start values\n for (var _i = valueIndex; _i > 0; _i -= 1) {\n var _changed = true;\n while (needPush(nextValues[_i] - nextValues[_i - 1]) && _changed) {\n var _offsetChangedValue2 = offsetChangedValue(nextValues, -1, _i - 1);\n nextValues[_i - 1] = _offsetChangedValue2.value;\n _changed = _offsetChangedValue2.changed;\n }\n }\n // >>>>> Revert back to safe push range\n // End to Start\n for (var _i2 = nextValues.length - 1; _i2 > 0; _i2 -= 1) {\n var _changed2 = true;\n while (needPush(nextValues[_i2] - nextValues[_i2 - 1]) && _changed2) {\n var _offsetChangedValue3 = offsetChangedValue(nextValues, -1, _i2 - 1);\n nextValues[_i2 - 1] = _offsetChangedValue3.value;\n _changed2 = _offsetChangedValue3.changed;\n }\n }\n // Start to End\n for (var _i3 = 0; _i3 < nextValues.length - 1; _i3 += 1) {\n var _changed3 = true;\n while (needPush(nextValues[_i3 + 1] - nextValues[_i3]) && _changed3) {\n var _offsetChangedValue4 = offsetChangedValue(nextValues, 1, _i3 + 1);\n nextValues[_i3 + 1] = _offsetChangedValue4.value;\n _changed3 = _offsetChangedValue4.changed;\n }\n }\n }\n return {\n value: nextValues[valueIndex],\n values: nextValues\n };\n };\n return [formatValue, offsetValues];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Slider.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar Slider = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _classNames;\n var _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-slider\' : _props$prefixCls,\n className = props.className,\n style = props.style,\n _props$disabled = props.disabled,\n disabled = _props$disabled === void 0 ? false : _props$disabled,\n _props$keyboard = props.keyboard,\n keyboard = _props$keyboard === void 0 ? true : _props$keyboard,\n autoFocus = props.autoFocus,\n onFocus = props.onFocus,\n onBlur = props.onBlur,\n _props$min = props.min,\n min = _props$min === void 0 ? 0 : _props$min,\n _props$max = props.max,\n max = _props$max === void 0 ? 100 : _props$max,\n _props$step = props.step,\n step = _props$step === void 0 ? 1 : _props$step,\n value = props.value,\n defaultValue = props.defaultValue,\n range = props.range,\n count = props.count,\n onChange = props.onChange,\n onBeforeChange = props.onBeforeChange,\n onAfterChange = props.onAfterChange,\n _props$allowCross = props.allowCross,\n allowCross = _props$allowCross === void 0 ? true : _props$allowCross,\n _props$pushable = props.pushable,\n pushable = _props$pushable === void 0 ? false : _props$pushable,\n draggableTrack = props.draggableTrack,\n reverse = props.reverse,\n vertical = props.vertical,\n _props$included = props.included,\n included = _props$included === void 0 ? true : _props$included,\n startPoint = props.startPoint,\n trackStyle = props.trackStyle,\n handleStyle = props.handleStyle,\n railStyle = props.railStyle,\n dotStyle = props.dotStyle,\n activeDotStyle = props.activeDotStyle,\n marks = props.marks,\n dots = props.dots,\n handleRender = props.handleRender,\n _props$tabIndex = props.tabIndex,\n tabIndex = _props$tabIndex === void 0 ? 0 : _props$tabIndex,\n ariaLabelForHandle = props.ariaLabelForHandle,\n ariaLabelledByForHandle = props.ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle = props.ariaValueTextFormatterForHandle;\n var handlesRef = react.useRef();\n var containerRef = react.useRef();\n var direction = react.useMemo(function () {\n if (vertical) {\n return reverse ? \'ttb\' : \'btt\';\n }\n return reverse ? \'rtl\' : \'ltr\';\n }, [reverse, vertical]);\n // ============================ Range =============================\n var mergedMin = react.useMemo(function () {\n return isFinite(min) ? min : 0;\n }, [min]);\n var mergedMax = react.useMemo(function () {\n return isFinite(max) ? max : 100;\n }, [max]);\n // ============================= Step =============================\n var mergedStep = react.useMemo(function () {\n return step !== null && step <= 0 ? 1 : step;\n }, [step]);\n // ============================= Push =============================\n var mergedPush = react.useMemo(function () {\n if (pushable === true) {\n return mergedStep;\n }\n return pushable >= 0 ? pushable : false;\n }, [pushable, mergedStep]);\n // ============================ Marks =============================\n var markList = react.useMemo(function () {\n var keys = Object.keys(marks || {});\n return keys.map(function (key) {\n var mark = marks[key];\n var markObj = {\n value: Number(key)\n };\n if (mark && typeof_typeof(mark) === \'object\' && ! /*#__PURE__*/react.isValidElement(mark) && (\'label\' in mark || \'style\' in mark)) {\n markObj.style = mark.style;\n markObj.label = mark.label;\n } else {\n markObj.label = mark;\n }\n return markObj;\n }).filter(function (_ref) {\n var label = _ref.label;\n return label || typeof label === \'number\';\n }).sort(function (a, b) {\n return a.value - b.value;\n });\n }, [marks]);\n // ============================ Format ============================\n var _useOffset = useOffset(mergedMin, mergedMax, mergedStep, markList, allowCross, mergedPush),\n _useOffset2 = slicedToArray_slicedToArray(_useOffset, 2),\n formatValue = _useOffset2[0],\n offsetValues = _useOffset2[1];\n // ============================ Values ============================\n var _useMergedState = useMergedState(defaultValue, {\n value: value\n }),\n _useMergedState2 = slicedToArray_slicedToArray(_useMergedState, 2),\n mergedValue = _useMergedState2[0],\n setValue = _useMergedState2[1];\n var rawValues = react.useMemo(function () {\n var valueList = mergedValue === null || mergedValue === undefined ? [] : Array.isArray(mergedValue) ? mergedValue : [mergedValue];\n var _valueList = slicedToArray_slicedToArray(valueList, 1),\n _valueList$ = _valueList[0],\n val0 = _valueList$ === void 0 ? mergedMin : _valueList$;\n var returnValues = mergedValue === null ? [] : [val0];\n // Format as range\n if (range) {\n returnValues = _toConsumableArray(valueList);\n // When count provided or value is `undefined`, we fill values\n if (count || mergedValue === undefined) {\n var pointCount = count >= 0 ? count + 1 : 2;\n returnValues = returnValues.slice(0, pointCount);\n // Fill with count\n while (returnValues.length < pointCount) {\n var _returnValues;\n returnValues.push((_returnValues = returnValues[returnValues.length - 1]) !== null && _returnValues !== void 0 ? _returnValues : mergedMin);\n }\n }\n returnValues.sort(function (a, b) {\n return a - b;\n });\n }\n // Align in range\n returnValues.forEach(function (val, index) {\n returnValues[index] = formatValue(val);\n });\n return returnValues;\n }, [mergedValue, range, mergedMin, count, formatValue]);\n // =========================== onChange ===========================\n var rawValuesRef = react.useRef(rawValues);\n rawValuesRef.current = rawValues;\n var getTriggerValue = function getTriggerValue(triggerValues) {\n return range ? triggerValues : triggerValues[0];\n };\n var triggerChange = function triggerChange(nextValues) {\n // Order first\n var cloneNextValues = _toConsumableArray(nextValues).sort(function (a, b) {\n return a - b;\n });\n // Trigger event if needed\n if (onChange && !es_isEqual(cloneNextValues, rawValuesRef.current, true)) {\n onChange(getTriggerValue(cloneNextValues));\n }\n // We set this later since it will re-render component immediately\n setValue(cloneNextValues);\n };\n var changeToCloseValue = function changeToCloseValue(newValue) {\n if (!disabled) {\n var valueIndex = 0;\n var valueDist = mergedMax - mergedMin;\n rawValues.forEach(function (val, index) {\n var dist = Math.abs(newValue - val);\n if (dist <= valueDist) {\n valueDist = dist;\n valueIndex = index;\n }\n });\n // Create new values\n var cloneNextValues = _toConsumableArray(rawValues);\n cloneNextValues[valueIndex] = newValue;\n // Fill value to match default 2\n if (range && !rawValues.length && count === undefined) {\n cloneNextValues.push(newValue);\n }\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(cloneNextValues));\n triggerChange(cloneNextValues);\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(cloneNextValues));\n }\n };\n // ============================ Click =============================\n var onSliderMouseDown = function onSliderMouseDown(e) {\n e.preventDefault();\n var _containerRef$current = containerRef.current.getBoundingClientRect(),\n width = _containerRef$current.width,\n height = _containerRef$current.height,\n left = _containerRef$current.left,\n top = _containerRef$current.top,\n bottom = _containerRef$current.bottom,\n right = _containerRef$current.right;\n var clientX = e.clientX,\n clientY = e.clientY;\n var percent;\n switch (direction) {\n case \'btt\':\n percent = (bottom - clientY) / height;\n break;\n case \'ttb\':\n percent = (clientY - top) / height;\n break;\n case \'rtl\':\n percent = (right - clientX) / width;\n break;\n default:\n percent = (clientX - left) / width;\n }\n var nextValue = mergedMin + percent * (mergedMax - mergedMin);\n changeToCloseValue(formatValue(nextValue));\n };\n // =========================== Keyboard ===========================\n var _React$useState = react.useState(null),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n keyboardValue = _React$useState2[0],\n setKeyboardValue = _React$useState2[1];\n var onHandleOffsetChange = function onHandleOffsetChange(offset, valueIndex) {\n if (!disabled) {\n var next = offsetValues(rawValues, offset, valueIndex);\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(rawValues));\n triggerChange(next.values);\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(next.values));\n setKeyboardValue(next.value);\n }\n };\n react.useEffect(function () {\n if (keyboardValue !== null) {\n var valueIndex = rawValues.indexOf(keyboardValue);\n if (valueIndex >= 0) {\n handlesRef.current.focus(valueIndex);\n }\n }\n setKeyboardValue(null);\n }, [keyboardValue]);\n // ============================= Drag =============================\n var mergedDraggableTrack = react.useMemo(function () {\n if (draggableTrack && mergedStep === null) {\n if (false) {}\n return false;\n }\n return draggableTrack;\n }, [draggableTrack, mergedStep]);\n var finishChange = function finishChange() {\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(rawValuesRef.current));\n };\n var _useDrag = useDrag(containerRef, direction, rawValues, mergedMin, mergedMax, formatValue, triggerChange, finishChange, offsetValues),\n _useDrag2 = slicedToArray_slicedToArray(_useDrag, 4),\n draggingIndex = _useDrag2[0],\n draggingValue = _useDrag2[1],\n cacheValues = _useDrag2[2],\n onStartDrag = _useDrag2[3];\n var onStartMove = function onStartMove(e, valueIndex) {\n onStartDrag(e, valueIndex);\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(rawValuesRef.current));\n };\n // Auto focus for updated handle\n var dragging = draggingIndex !== -1;\n react.useEffect(function () {\n if (!dragging) {\n var valueIndex = rawValues.lastIndexOf(draggingValue);\n handlesRef.current.focus(valueIndex);\n }\n }, [dragging]);\n // =========================== Included ===========================\n var sortedCacheValues = react.useMemo(function () {\n return _toConsumableArray(cacheValues).sort(function (a, b) {\n return a - b;\n });\n }, [cacheValues]);\n // Provide a range values with included [min, max]\n // Used for Track, Mark & Dot\n var _React$useMemo = react.useMemo(function () {\n if (!range) {\n return [mergedMin, sortedCacheValues[0]];\n }\n return [sortedCacheValues[0], sortedCacheValues[sortedCacheValues.length - 1]];\n }, [sortedCacheValues, range, mergedMin]),\n _React$useMemo2 = slicedToArray_slicedToArray(_React$useMemo, 2),\n includedStart = _React$useMemo2[0],\n includedEnd = _React$useMemo2[1];\n // ============================= Refs =============================\n react.useImperativeHandle(ref, function () {\n return {\n focus: function focus() {\n handlesRef.current.focus(0);\n },\n blur: function blur() {\n var _document = document,\n activeElement = _document.activeElement;\n if (containerRef.current.contains(activeElement)) {\n activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur();\n }\n }\n };\n });\n // ========================== Auto Focus ==========================\n react.useEffect(function () {\n if (autoFocus) {\n handlesRef.current.focus(0);\n }\n }, []);\n // =========================== Context ============================\n var context = react.useMemo(function () {\n return {\n min: mergedMin,\n max: mergedMax,\n direction: direction,\n disabled: disabled,\n keyboard: keyboard,\n step: mergedStep,\n included: included,\n includedStart: includedStart,\n includedEnd: includedEnd,\n range: range,\n tabIndex: tabIndex,\n ariaLabelForHandle: ariaLabelForHandle,\n ariaLabelledByForHandle: ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle: ariaValueTextFormatterForHandle\n };\n }, [mergedMin, mergedMax, direction, disabled, keyboard, mergedStep, included, includedStart, includedEnd, range, tabIndex, ariaLabelForHandle, ariaLabelledByForHandle, ariaValueTextFormatterForHandle]);\n // ============================ Render ============================\n return /*#__PURE__*/react.createElement(es_context.Provider, {\n value: context\n }, /*#__PURE__*/react.createElement("div", {\n ref: containerRef,\n className: classnames_default()(prefixCls, className, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls, "-vertical"), vertical), _defineProperty(_classNames, "".concat(prefixCls, "-horizontal"), !vertical), _defineProperty(_classNames, "".concat(prefixCls, "-with-marks"), markList.length), _classNames)),\n style: style,\n onMouseDown: onSliderMouseDown\n }, /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-rail"),\n style: railStyle\n }), /*#__PURE__*/react.createElement(Tracks, {\n prefixCls: prefixCls,\n style: trackStyle,\n values: sortedCacheValues,\n startPoint: startPoint,\n onStartMove: mergedDraggableTrack ? onStartMove : null\n }), /*#__PURE__*/react.createElement(Steps, {\n prefixCls: prefixCls,\n marks: markList,\n dots: dots,\n style: dotStyle,\n activeStyle: activeDotStyle\n }), /*#__PURE__*/react.createElement(es_Handles, {\n ref: handlesRef,\n prefixCls: prefixCls,\n style: handleStyle,\n values: cacheValues,\n draggingIndex: draggingIndex,\n onStartMove: onStartMove,\n onOffsetChange: onHandleOffsetChange,\n onFocus: onFocus,\n onBlur: onBlur,\n handleRender: handleRender\n }), /*#__PURE__*/react.createElement(Marks, {\n prefixCls: prefixCls,\n marks: markList,\n onClick: changeToCloseValue\n })));\n});\nif (false) {}\n/* harmony default export */ const es_Slider = (Slider);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/index.js\n\n/* harmony default export */ const es = (es_Slider);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\nvar injectStylesIntoStyleTag = __webpack_require__(379);\nvar injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js\nvar styleDomAPI = __webpack_require__(795);\nvar styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js\nvar insertBySelector = __webpack_require__(569);\nvar insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\nvar setAttributesWithoutAttributes = __webpack_require__(565);\nvar setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js\nvar insertStyleElement = __webpack_require__(216);\nvar insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js\nvar styleTagTransform = __webpack_require__(589);\nvar styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./node_modules/rc-tooltip/assets/bootstrap.css\nvar bootstrap = __webpack_require__(467);\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/assets/bootstrap.css\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (styleTagTransform_default());\noptions.setAttributes = (setAttributesWithoutAttributes_default());\n\n options.insert = insertBySelector_default().bind(null, "head");\n \noptions.domAPI = (styleDomAPI_default());\noptions.insertStyleElement = (insertStyleElement_default());\n\nvar update = injectStylesIntoStyleTag_default()(bootstrap/* default */.Z, options);\n\n\n\n\n /* harmony default export */ const assets_bootstrap = (bootstrap/* default */.Z && bootstrap/* default.locals */.Z.locals ? bootstrap/* default.locals */.Z.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/rc-util/lib/raf.js\nvar raf = __webpack_require__(543);\n// EXTERNAL MODULE: ./node_modules/react-dom/index.js\nvar react_dom = __webpack_require__(935);\n// EXTERNAL MODULE: ./node_modules/react-is/index.js\nvar react_is = __webpack_require__(864);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useMemo.js\n\nfunction useMemo(getValue, condition, shouldUpdate) {\n var cacheRef = react.useRef({});\n if (!(\'value\' in cacheRef.current) || shouldUpdate(cacheRef.current.condition, condition)) {\n cacheRef.current.value = getValue();\n cacheRef.current.condition = condition;\n }\n return cacheRef.current.value;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/ref.js\n\n/* eslint-disable no-param-reassign */\n\n\n\nfunction fillRef(ref, node) {\n if (typeof ref === \'function\') {\n ref(node);\n } else if (typeof_typeof(ref) === \'object\' && ref && \'current\' in ref) {\n ref.current = node;\n }\n}\n\n/**\n * Merge refs into one ref function to support ref passing.\n */\nfunction composeRef() {\n for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {\n refs[_key] = arguments[_key];\n }\n var refList = refs.filter(function (ref) {\n return ref;\n });\n if (refList.length <= 1) {\n return refList[0];\n }\n return function (node) {\n refs.forEach(function (ref) {\n fillRef(ref, node);\n });\n };\n}\nfunction useComposeRef() {\n for (var _len2 = arguments.length, refs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n refs[_key2] = arguments[_key2];\n }\n return useMemo(function () {\n return composeRef.apply(void 0, refs);\n }, refs, function (prev, next) {\n return prev.length === next.length && prev.every(function (ref, i) {\n return ref === next[i];\n });\n });\n}\nfunction supportRef(nodeOrComponent) {\n var _type$prototype, _nodeOrComponent$prot;\n var type = (0,react_is.isMemo)(nodeOrComponent) ? nodeOrComponent.type.type : nodeOrComponent.type;\n\n // Function component node\n if (typeof type === \'function\' && !((_type$prototype = type.prototype) !== null && _type$prototype !== void 0 && _type$prototype.render)) {\n return false;\n }\n\n // Class component\n if (typeof nodeOrComponent === \'function\' && !((_nodeOrComponent$prot = nodeOrComponent.prototype) !== null && _nodeOrComponent$prot !== void 0 && _nodeOrComponent$prot.render)) {\n return false;\n }\n return true;\n}\n/* eslint-enable */\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/Context.js\n\nvar OrderContext = /*#__PURE__*/react.createContext(null);\n/* harmony default export */ const es_Context = (OrderContext);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/useDom.js\n\n\n\n\n\n\nvar EMPTY_LIST = [];\n\n/**\n * Will add `div` to document. Nest call will keep order\n * @param render Render DOM in document\n */\nfunction useDom(render, debug) {\n var _React$useState = react.useState(function () {\n if (!canUseDom()) {\n return null;\n }\n var defaultEle = document.createElement(\'div\');\n if (false) {}\n return defaultEle;\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 1),\n ele = _React$useState2[0];\n\n // ========================== Order ==========================\n var appendedRef = react.useRef(false);\n var queueCreate = react.useContext(es_Context);\n var _React$useState3 = react.useState(EMPTY_LIST),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n queue = _React$useState4[0],\n setQueue = _React$useState4[1];\n var mergedQueueCreate = queueCreate || (appendedRef.current ? undefined : function (appendFn) {\n setQueue(function (origin) {\n var newQueue = [appendFn].concat(_toConsumableArray(origin));\n return newQueue;\n });\n });\n\n // =========================== DOM ===========================\n function append() {\n if (!ele.parentElement) {\n document.body.appendChild(ele);\n }\n appendedRef.current = true;\n }\n function cleanup() {\n var _ele$parentElement;\n (_ele$parentElement = ele.parentElement) === null || _ele$parentElement === void 0 ? void 0 : _ele$parentElement.removeChild(ele);\n appendedRef.current = false;\n }\n hooks_useLayoutEffect(function () {\n if (render) {\n if (queueCreate) {\n queueCreate(append);\n } else {\n append();\n }\n } else {\n cleanup();\n }\n return cleanup;\n }, [render]);\n hooks_useLayoutEffect(function () {\n if (queue.length) {\n queue.forEach(function (appendFn) {\n return appendFn();\n });\n setQueue(EMPTY_LIST);\n }\n }, [queue]);\n return [ele, mergedQueueCreate];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/contains.js\nfunction contains(root, n) {\n if (!root) {\n return false;\n }\n\n // Use native if support\n if (root.contains) {\n return root.contains(n);\n }\n\n // `document.contains` not support with IE11\n var node = n;\n while (node) {\n if (node === root) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/dynamicCSS.js\n\n\nvar APPEND_ORDER = \'data-rc-order\';\nvar MARK_KEY = "rc-util-key";\nvar containerCache = new Map();\nfunction getMark() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n mark = _ref.mark;\n if (mark) {\n return mark.startsWith(\'data-\') ? mark : "data-".concat(mark);\n }\n return MARK_KEY;\n}\nfunction getContainer(option) {\n if (option.attachTo) {\n return option.attachTo;\n }\n var head = document.querySelector(\'head\');\n return head || document.body;\n}\nfunction getOrder(prepend) {\n if (prepend === \'queue\') {\n return \'prependQueue\';\n }\n return prepend ? \'prepend\' : \'append\';\n}\n\n/**\n * Find style which inject by rc-util\n */\nfunction findStyles(container) {\n return Array.from((containerCache.get(container) || container).children).filter(function (node) {\n return node.tagName === \'STYLE\';\n });\n}\nfunction injectCSS(css) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (!canUseDom()) {\n return null;\n }\n var csp = option.csp,\n prepend = option.prepend;\n var styleNode = document.createElement(\'style\');\n styleNode.setAttribute(APPEND_ORDER, getOrder(prepend));\n if (csp !== null && csp !== void 0 && csp.nonce) {\n styleNode.nonce = csp === null || csp === void 0 ? void 0 : csp.nonce;\n }\n styleNode.innerHTML = css;\n var container = getContainer(option);\n var firstChild = container.firstChild;\n if (prepend) {\n // If is queue `prepend`, it will prepend first style and then append rest style\n if (prepend === \'queue\') {\n var existStyle = findStyles(container).filter(function (node) {\n return [\'prepend\', \'prependQueue\'].includes(node.getAttribute(APPEND_ORDER));\n });\n if (existStyle.length) {\n container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);\n return styleNode;\n }\n }\n\n // Use `insertBefore` as `prepend`\n container.insertBefore(styleNode, firstChild);\n } else {\n container.appendChild(styleNode);\n }\n return styleNode;\n}\nfunction findExistNode(key) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var container = getContainer(option);\n return findStyles(container).find(function (node) {\n return node.getAttribute(getMark(option)) === key;\n });\n}\nfunction removeCSS(key) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var existNode = findExistNode(key, option);\n if (existNode) {\n var container = getContainer(option);\n container.removeChild(existNode);\n }\n}\n\n/**\n * qiankun will inject `appendChild` to insert into other\n */\nfunction syncRealContainer(container, option) {\n var cachedRealContainer = containerCache.get(container);\n\n // Find real container when not cached or cached container removed\n if (!cachedRealContainer || !contains(document, cachedRealContainer)) {\n var placeholderStyle = injectCSS(\'\', option);\n var parentNode = placeholderStyle.parentNode;\n containerCache.set(container, parentNode);\n container.removeChild(placeholderStyle);\n }\n}\n\n/**\n * manually clear container cache to avoid global cache in unit testes\n */\nfunction clearContainerCache() {\n containerCache.clear();\n}\nfunction updateCSS(css, key) {\n var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var container = getContainer(option);\n\n // Sync real parent\n syncRealContainer(container, option);\n var existNode = findExistNode(key, option);\n if (existNode) {\n var _option$csp, _option$csp2;\n if ((_option$csp = option.csp) !== null && _option$csp !== void 0 && _option$csp.nonce && existNode.nonce !== ((_option$csp2 = option.csp) === null || _option$csp2 === void 0 ? void 0 : _option$csp2.nonce)) {\n var _option$csp3;\n existNode.nonce = (_option$csp3 = option.csp) === null || _option$csp3 === void 0 ? void 0 : _option$csp3.nonce;\n }\n if (existNode.innerHTML !== css) {\n existNode.innerHTML = css;\n }\n return existNode;\n }\n var newNode = injectCSS(css, option);\n newNode.setAttribute(getMark(option), key);\n return newNode;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/getScrollBarSize.js\n/* eslint-disable no-param-reassign */\n\nvar cached;\nfunction getScrollBarSize(fresh) {\n if (typeof document === \'undefined\') {\n return 0;\n }\n if (fresh || cached === undefined) {\n var inner = document.createElement(\'div\');\n inner.style.width = \'100%\';\n inner.style.height = \'200px\';\n var outer = document.createElement(\'div\');\n var outerStyle = outer.style;\n outerStyle.position = \'absolute\';\n outerStyle.top = \'0\';\n outerStyle.left = \'0\';\n outerStyle.pointerEvents = \'none\';\n outerStyle.visibility = \'hidden\';\n outerStyle.width = \'200px\';\n outerStyle.height = \'150px\';\n outerStyle.overflow = \'hidden\';\n outer.appendChild(inner);\n document.body.appendChild(outer);\n var widthContained = inner.offsetWidth;\n outer.style.overflow = \'scroll\';\n var widthScroll = inner.offsetWidth;\n if (widthContained === widthScroll) {\n widthScroll = outer.clientWidth;\n }\n document.body.removeChild(outer);\n cached = widthContained - widthScroll;\n }\n return cached;\n}\nfunction ensureSize(str) {\n var match = str.match(/^(.*)px$/);\n var value = Number(match === null || match === void 0 ? void 0 : match[1]);\n return Number.isNaN(value) ? getScrollBarSize() : value;\n}\nfunction getTargetScrollBarSize(target) {\n if (typeof document === \'undefined\' || !target || !(target instanceof Element)) {\n return {\n width: 0,\n height: 0\n };\n }\n var _getComputedStyle = getComputedStyle(target, \'::-webkit-scrollbar\'),\n width = _getComputedStyle.width,\n height = _getComputedStyle.height;\n return {\n width: ensureSize(width),\n height: ensureSize(height)\n };\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/util.js\n/**\n * Test usage export. Do not use in your production\n */\nfunction isBodyOverflowing() {\n return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) && window.innerWidth > document.body.offsetWidth;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/useScrollLocker.js\n\n\n\n\n\n\nvar UNIQUE_ID = "rc-util-locker-".concat(Date.now());\nvar uuid = 0;\nfunction useScrollLocker(lock) {\n var mergedLock = !!lock;\n var _React$useState = react.useState(function () {\n uuid += 1;\n return "".concat(UNIQUE_ID, "_").concat(uuid);\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 1),\n id = _React$useState2[0];\n hooks_useLayoutEffect(function () {\n if (mergedLock) {\n var scrollbarSize = getScrollBarSize();\n var isOverflow = isBodyOverflowing();\n updateCSS("\\nhtml body {\\n overflow-y: hidden;\\n ".concat(isOverflow ? "width: calc(100% - ".concat(scrollbarSize, "px);") : \'\', "\\n}"), id);\n } else {\n removeCSS(id);\n }\n return function () {\n removeCSS(id);\n };\n }, [mergedLock, id]);\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/mock.js\nvar inline = false;\nfunction inlineMock(nextInline) {\n if (typeof nextInline === \'boolean\') {\n inline = nextInline;\n }\n return inline;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/Portal.js\n\n\n\n\n\n\n\n\n\n\nvar getPortalContainer = function getPortalContainer(getContainer) {\n if (getContainer === false) {\n return false;\n }\n if (!canUseDom() || !getContainer) {\n return null;\n }\n if (typeof getContainer === \'string\') {\n return document.querySelector(getContainer);\n }\n if (typeof getContainer === \'function\') {\n return getContainer();\n }\n return getContainer;\n};\nvar Portal = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var open = props.open,\n autoLock = props.autoLock,\n getContainer = props.getContainer,\n debug = props.debug,\n _props$autoDestroy = props.autoDestroy,\n autoDestroy = _props$autoDestroy === void 0 ? true : _props$autoDestroy,\n children = props.children;\n var _React$useState = react.useState(open),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n shouldRender = _React$useState2[0],\n setShouldRender = _React$useState2[1];\n var mergedRender = shouldRender || open;\n\n // ========================= Warning =========================\n if (false) {}\n\n // ====================== Should Render ======================\n react.useEffect(function () {\n if (autoDestroy || open) {\n setShouldRender(open);\n }\n }, [open, autoDestroy]);\n\n // ======================== Container ========================\n var _React$useState3 = react.useState(function () {\n return getPortalContainer(getContainer);\n }),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n innerContainer = _React$useState4[0],\n setInnerContainer = _React$useState4[1];\n react.useEffect(function () {\n var customizeContainer = getPortalContainer(getContainer);\n\n // Tell component that we check this in effect which is safe to be `null`\n setInnerContainer(customizeContainer !== null && customizeContainer !== void 0 ? customizeContainer : null);\n });\n var _useDom = useDom(mergedRender && !innerContainer, debug),\n _useDom2 = slicedToArray_slicedToArray(_useDom, 2),\n defaultContainer = _useDom2[0],\n queueCreate = _useDom2[1];\n var mergedContainer = innerContainer !== null && innerContainer !== void 0 ? innerContainer : defaultContainer;\n\n // ========================= Locker ==========================\n useScrollLocker(autoLock && open && canUseDom() && (mergedContainer === defaultContainer || mergedContainer === document.body));\n\n // =========================== Ref ===========================\n var childRef = null;\n if (children && supportRef(children) && ref) {\n var _ref = children;\n childRef = _ref.ref;\n }\n var mergedRef = useComposeRef(childRef, ref);\n\n // ========================= Render ==========================\n // Do not render when nothing need render\n // When innerContainer is `undefined`, it may not ready since user use ref in the same render\n if (!mergedRender || !canUseDom() || innerContainer === undefined) {\n return null;\n }\n\n // Render inline\n var renderInline = mergedContainer === false || inlineMock();\n var reffedChildren = children;\n if (ref) {\n reffedChildren = /*#__PURE__*/react.cloneElement(children, {\n ref: mergedRef\n });\n }\n return /*#__PURE__*/react.createElement(es_Context.Provider, {\n value: queueCreate\n }, renderInline ? reffedChildren : /*#__PURE__*/(0,react_dom.createPortal)(reffedChildren, mergedContainer));\n});\nif (false) {}\n/* harmony default export */ const es_Portal = (Portal);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/index.js\n\n\n\n/* harmony default export */ const portal_es = (es_Portal);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Children/toArray.js\n\n\nfunction toArray(children) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var ret = [];\n react.Children.forEach(children, function (child) {\n if ((child === undefined || child === null) && !option.keepEmpty) {\n return;\n }\n if (Array.isArray(child)) {\n ret = ret.concat(toArray(child));\n } else if ((0,react_is.isFragment)(child) && child.props) {\n ret = ret.concat(toArray(child.props.children, option));\n } else {\n ret.push(child);\n }\n });\n return ret;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/findDOMNode.js\n\n\nfunction isDOM(node) {\n // https://developer.mozilla.org/en-US/docs/Web/API/Element\n // Since XULElement is also subclass of Element, we only need HTMLElement and SVGElement\n return node instanceof HTMLElement || node instanceof SVGElement;\n}\n\n/**\n * Return if a node is a DOM node. Else will return by `findDOMNode`\n */\nfunction findDOMNode(node) {\n if (isDOM(node)) {\n return node;\n }\n if (node instanceof react.Component) {\n return react_dom.findDOMNode(node);\n }\n return null;\n}\n;// CONCATENATED MODULE: ./node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js\n/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== \'undefined\') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array<Array>} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, "size", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== \'undefined\' && typeof document !== \'undefined\' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof __webpack_require__.g !== \'undefined\' && __webpack_require__.g.Math === Math) {\r\n return __webpack_require__.g;\r\n }\r\n if (typeof self !== \'undefined\' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== \'undefined\' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function(\'return this\')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests\' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === \'function\') {\r\n // It\'s required to use a bounded function because IE sometimes throws\r\n // an "Invalid calling object" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the "proxy" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for "transitions" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = [\'top\', \'right\', \'bottom\', \'left\', \'width\', \'height\', \'size\', \'weight\'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== \'undefined\';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array<ResizeObserverSPI>}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven\'t been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it\'s present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns "true" if any observer has detected changes in\r\n * dimensions of it\'s elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the "Transitionend" event is used as a workaround for\r\n // delayed transitions. This way it\'s possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener(\'transitionend\', this.onTransitionEnd_);\r\n window.addEventListener(\'resize\', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener(\'DOMSubtreeModified\', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener(\'transitionend\', this.onTransitionEnd_);\r\n window.removeEventListener(\'resize\', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener(\'DOMSubtreeModified\', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * "Transitionend" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? \'\' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller\'s instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the "ownerDocument" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it\'s not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles[\'border-\' + position + \'-width\'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = [\'top\', \'right\', \'bottom\', \'left\'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles[\'padding-\' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can\'t be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it\'s not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery\'s \':visible\' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it\'s data wasn\'t\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the \'border-box\' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === \'border-box\') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn\'t include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the "client"\r\n // properties then it\'s either IE, and thus we don\'t need to subtract\r\n // anything, or an element merely doesn\'t have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, \'left\', \'right\') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, \'top\', \'bottom\') + vertPad;\r\n }\r\n }\r\n // Following steps can\'t be applied to the document\'s root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it\'s as well not necessary as the <html> itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and "client" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of "client" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn\'t happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don\'t have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== \'undefined\') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it\'s so, then check that element is at least an instance of the\r\n // SVGElement and that it has the "getBBox" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === \'function\'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element (<html>).\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle\'s x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== \'undefined\' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle\'s properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle\'s width.\r\n * @param {number} height - Rectangle\'s height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it\'s changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it\'s width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates \'broadcastWidth\' and \'broadcastHeight\' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element\'s content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they\'d require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don\'t support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it\'s content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array<ResizeObservation>}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map<Element, ResizeObservation>}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== \'function\') {\r\n throw new TypeError(\'The callback provided as parameter 1 is not a function.\');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n // Do nothing if current environment doesn\'t have the Element interface.\r\n if (typeof Element === \'undefined\' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError(\'parameter 1 is not of type "Element".\');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n // Do nothing if current environment doesn\'t have the Element interface.\r\n if (typeof Element === \'undefined\' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError(\'parameter 1 is not of type "Element".\');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it\'s content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn\'t have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can\'t be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== \'undefined\' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError(\'Cannot call a class as a function.\');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n \'observe\',\r\n \'unobserve\',\r\n \'disconnect\'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== \'undefined\') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\n/* harmony default export */ const ResizeObserver_es = (index);\n\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/utils/observerUtil.js\n\n// =============================== Const ===============================\nvar elementListeners = new Map();\nfunction onResize(entities) {\n entities.forEach(function (entity) {\n var _elementListeners$get;\n var target = entity.target;\n (_elementListeners$get = elementListeners.get(target)) === null || _elementListeners$get === void 0 ? void 0 : _elementListeners$get.forEach(function (listener) {\n return listener(target);\n });\n });\n}\n// Note: ResizeObserver polyfill not support option to measure border-box resize\nvar resizeObserver = new ResizeObserver_es(onResize);\n// Dev env only\nvar _el = (/* unused pure expression or super */ null && ( false ? 0 : null)); // eslint-disable-line\nvar _rs = (/* unused pure expression or super */ null && ( false ? 0 : null)); // eslint-disable-line\n// ============================== Observe ==============================\nfunction observe(element, callback) {\n if (!elementListeners.has(element)) {\n elementListeners.set(element, new Set());\n resizeObserver.observe(element);\n }\n elementListeners.get(element).add(callback);\n}\nfunction unobserve(element, callback) {\n if (elementListeners.has(element)) {\n elementListeners.get(element).delete(callback);\n if (!elementListeners.get(element).size) {\n resizeObserver.unobserve(element);\n elementListeners.delete(element);\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js\nfunction classCallCheck_classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js\n\nfunction createClass_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_toPropertyKey(descriptor.key), descriptor);\n }\n}\nfunction createClass_createClass(Constructor, protoProps, staticProps) {\n if (protoProps) createClass_defineProperties(Constructor.prototype, protoProps);\n if (staticProps) createClass_defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== "function" && superClass !== null) {\n throw new TypeError("Super expression must either be null or a function");\n }\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, "prototype", {\n writable: false\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nfunction _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js\nfunction _isNativeReflectConstruct() {\n if (typeof Reflect === "undefined" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === "function") return true;\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js\nfunction _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called");\n }\n return self;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js\n\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (typeof_typeof(call) === "object" || typeof call === "function")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError("Derived constructors may only return object or undefined");\n }\n return _assertThisInitialized(self);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createSuper.js\n\n\n\nfunction _createSuper(Derived) {\n var hasNativeReflectConstruct = _isNativeReflectConstruct();\n return function _createSuperInternal() {\n var Super = _getPrototypeOf(Derived),\n result;\n if (hasNativeReflectConstruct) {\n var NewTarget = _getPrototypeOf(this).constructor;\n result = Reflect.construct(Super, arguments, NewTarget);\n } else {\n result = Super.apply(this, arguments);\n }\n return _possibleConstructorReturn(this, result);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/SingleObserver/DomWrapper.js\n\n\n\n\n\n/**\n * Fallback to findDOMNode if origin ref do not provide any dom element\n */\nvar DomWrapper = /*#__PURE__*/function (_React$Component) {\n _inherits(DomWrapper, _React$Component);\n var _super = _createSuper(DomWrapper);\n function DomWrapper() {\n classCallCheck_classCallCheck(this, DomWrapper);\n return _super.apply(this, arguments);\n }\n createClass_createClass(DomWrapper, [{\n key: "render",\n value: function render() {\n return this.props.children;\n }\n }]);\n return DomWrapper;\n}(react.Component);\n\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/Collection.js\n\nvar CollectionContext = /*#__PURE__*/react.createContext(null);\n/**\n * Collect all the resize event from children ResizeObserver\n */\nfunction Collection(_ref) {\n var children = _ref.children,\n onBatchResize = _ref.onBatchResize;\n var resizeIdRef = react.useRef(0);\n var resizeInfosRef = react.useRef([]);\n var onCollectionResize = react.useContext(CollectionContext);\n var onResize = react.useCallback(function (size, element, data) {\n resizeIdRef.current += 1;\n var currentId = resizeIdRef.current;\n resizeInfosRef.current.push({\n size: size,\n element: element,\n data: data\n });\n Promise.resolve().then(function () {\n if (currentId === resizeIdRef.current) {\n onBatchResize === null || onBatchResize === void 0 ? void 0 : onBatchResize(resizeInfosRef.current);\n resizeInfosRef.current = [];\n }\n });\n // Continue bubbling if parent exist\n onCollectionResize === null || onCollectionResize === void 0 ? void 0 : onCollectionResize(size, element, data);\n }, [onBatchResize, onCollectionResize]);\n return /*#__PURE__*/react.createElement(CollectionContext.Provider, {\n value: onResize\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/SingleObserver/index.js\n\n\n\n\n\n\n\nfunction SingleObserver(props, ref) {\n var children = props.children,\n disabled = props.disabled;\n var elementRef = react.useRef(null);\n var wrapperRef = react.useRef(null);\n var onCollectionResize = react.useContext(CollectionContext);\n // =========================== Children ===========================\n var isRenderProps = typeof children === \'function\';\n var mergedChildren = isRenderProps ? children(elementRef) : children;\n // ============================= Size =============================\n var sizeRef = react.useRef({\n width: -1,\n height: -1,\n offsetWidth: -1,\n offsetHeight: -1\n });\n // ============================= Ref ==============================\n var canRef = !isRenderProps && /*#__PURE__*/react.isValidElement(mergedChildren) && supportRef(mergedChildren);\n var originRef = canRef ? mergedChildren.ref : null;\n var mergedRef = react.useMemo(function () {\n return composeRef(originRef, elementRef);\n }, [originRef, elementRef]);\n var getDom = function getDom() {\n return findDOMNode(elementRef.current) || findDOMNode(wrapperRef.current);\n };\n react.useImperativeHandle(ref, function () {\n return getDom();\n });\n // =========================== Observe ============================\n var propsRef = react.useRef(props);\n propsRef.current = props;\n // Handler\n var onInternalResize = react.useCallback(function (target) {\n var _propsRef$current = propsRef.current,\n onResize = _propsRef$current.onResize,\n data = _propsRef$current.data;\n var _target$getBoundingCl = target.getBoundingClientRect(),\n width = _target$getBoundingCl.width,\n height = _target$getBoundingCl.height;\n var offsetWidth = target.offsetWidth,\n offsetHeight = target.offsetHeight;\n /**\n * Resize observer trigger when content size changed.\n * In most case we just care about element size,\n * let\'s use `boundary` instead of `contentRect` here to avoid shaking.\n */\n var fixedWidth = Math.floor(width);\n var fixedHeight = Math.floor(height);\n if (sizeRef.current.width !== fixedWidth || sizeRef.current.height !== fixedHeight || sizeRef.current.offsetWidth !== offsetWidth || sizeRef.current.offsetHeight !== offsetHeight) {\n var size = {\n width: fixedWidth,\n height: fixedHeight,\n offsetWidth: offsetWidth,\n offsetHeight: offsetHeight\n };\n sizeRef.current = size;\n // IE is strange, right?\n var mergedOffsetWidth = offsetWidth === Math.round(width) ? width : offsetWidth;\n var mergedOffsetHeight = offsetHeight === Math.round(height) ? height : offsetHeight;\n var sizeInfo = _objectSpread2(_objectSpread2({}, size), {}, {\n offsetWidth: mergedOffsetWidth,\n offsetHeight: mergedOffsetHeight\n });\n // Let collection know what happened\n onCollectionResize === null || onCollectionResize === void 0 ? void 0 : onCollectionResize(sizeInfo, target, data);\n if (onResize) {\n // defer the callback but not defer to next frame\n Promise.resolve().then(function () {\n onResize(sizeInfo, target);\n });\n }\n }\n }, []);\n // Dynamic observe\n react.useEffect(function () {\n var currentElement = getDom();\n if (currentElement && !disabled) {\n observe(currentElement, onInternalResize);\n }\n return function () {\n return unobserve(currentElement, onInternalResize);\n };\n }, [elementRef.current, disabled]);\n // ============================ Render ============================\n return /*#__PURE__*/react.createElement(DomWrapper, {\n ref: wrapperRef\n }, canRef ? /*#__PURE__*/react.cloneElement(mergedChildren, {\n ref: mergedRef\n }) : mergedChildren);\n}\nvar RefSingleObserver = /*#__PURE__*/react.forwardRef(SingleObserver);\nif (false) {}\n/* harmony default export */ const es_SingleObserver = (RefSingleObserver);\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/index.js\n\n\n\n\n\n\nvar INTERNAL_PREFIX_KEY = \'rc-observer-key\';\n\n\nfunction es_ResizeObserver(props, ref) {\n var children = props.children;\n var childNodes = typeof children === \'function\' ? [children] : toArray(children);\n if (false) {}\n return childNodes.map(function (child, index) {\n var key = (child === null || child === void 0 ? void 0 : child.key) || "".concat(INTERNAL_PREFIX_KEY, "-").concat(index);\n return /*#__PURE__*/react.createElement(es_SingleObserver, extends_extends({}, props, {\n key: key,\n ref: index === 0 ? ref : undefined\n }), child);\n });\n}\nvar RefResizeObserver = /*#__PURE__*/react.forwardRef(es_ResizeObserver);\nif (false) {}\nRefResizeObserver.Collection = Collection;\n/* harmony default export */ const rc_resize_observer_es = (RefResizeObserver);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useId.js\n\n\n\nfunction getUseId() {\n // We need fully clone React function here to avoid webpack warning React 17 do not export `useId`\n var fullClone = _objectSpread2({}, react_namespaceObject);\n return fullClone.useId;\n}\nvar useId_uuid = 0;\n\n/** @private Note only worked in develop env. Not work in production. */\nfunction resetUuid() {\n if (false) {}\n}\nfunction useId(id) {\n // Inner id for accessibility usage. Only work in client side\n var _React$useState = react.useState(\'ssr-id\'),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n innerId = _React$useState2[0],\n setInnerId = _React$useState2[1];\n var useOriginId = getUseId();\n var reactNativeId = useOriginId === null || useOriginId === void 0 ? void 0 : useOriginId();\n react.useEffect(function () {\n if (!useOriginId) {\n var nextId = useId_uuid;\n useId_uuid += 1;\n setInnerId("rc_unique_".concat(nextId));\n }\n }, []);\n\n // Developer passed id is single source of truth\n if (id) {\n return id;\n }\n\n // Test env always return mock id\n if (false) {}\n\n // Return react native id or inner id\n return reactNativeId || innerId;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/isMobile.js\n/* harmony default export */ const es_isMobile = (function () {\n if (typeof navigator === \'undefined\' || typeof window === \'undefined\') {\n return false;\n }\n var agent = navigator.userAgent || navigator.vendor || window.opera;\n return /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(agent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(agent === null || agent === void 0 ? void 0 : agent.substr(0, 4));\n});\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/context.js\n\nvar TriggerContext = /*#__PURE__*/react.createContext(null);\n/* harmony default export */ const trigger_es_context = (TriggerContext);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useAction.js\n\nfunction useAction_toArray(val) {\n return val ? Array.isArray(val) ? val : [val] : [];\n}\nfunction useAction(mobile, action, showAction, hideAction) {\n return react.useMemo(function () {\n var mergedShowAction = useAction_toArray(showAction !== null && showAction !== void 0 ? showAction : action);\n var mergedHideAction = useAction_toArray(hideAction !== null && hideAction !== void 0 ? hideAction : action);\n var showActionSet = new Set(mergedShowAction);\n var hideActionSet = new Set(mergedHideAction);\n if (mobile) {\n if (showActionSet.has(\'hover\')) {\n showActionSet.delete(\'hover\');\n showActionSet.add(\'click\');\n }\n if (hideActionSet.has(\'hover\')) {\n hideActionSet.delete(\'hover\');\n hideActionSet.add(\'click\');\n }\n }\n return [showActionSet, hideActionSet];\n }, [mobile, action, showAction, hideAction]);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/isVisible.js\n/* harmony default export */ const isVisible = (function (element) {\n if (!element) {\n return false;\n }\n if (element instanceof Element) {\n if (element.offsetParent) {\n return true;\n }\n if (element.getBBox) {\n var _getBBox = element.getBBox(),\n width = _getBBox.width,\n height = _getBBox.height;\n if (width || height) {\n return true;\n }\n }\n if (element.getBoundingClientRect) {\n var _element$getBoundingC = element.getBoundingClientRect(),\n _width = _element$getBoundingC.width,\n _height = _element$getBoundingC.height;\n if (_width || _height) {\n return true;\n }\n }\n }\n return false;\n});\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/util.js\n\nfunction isPointsEq() {\n var a1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var a2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n var isAlignPoint = arguments.length > 2 ? arguments[2] : undefined;\n if (isAlignPoint) {\n return a1[0] === a2[0];\n }\n return a1[0] === a2[0] && a1[1] === a2[1];\n}\nfunction getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) {\n var points = align.points;\n var placements = Object.keys(builtinPlacements);\n for (var i = 0; i < placements.length; i += 1) {\n var _builtinPlacements$pl;\n var placement = placements[i];\n if (isPointsEq((_builtinPlacements$pl = builtinPlacements[placement]) === null || _builtinPlacements$pl === void 0 ? void 0 : _builtinPlacements$pl.points, points, isAlignPoint)) {\n return "".concat(prefixCls, "-placement-").concat(placement);\n }\n }\n return \'\';\n}\n\n/** @deprecated We should not use this if we can refactor all deps */\nfunction getMotion(prefixCls, motion, animation, transitionName) {\n if (motion) {\n return motion;\n }\n if (animation) {\n return {\n motionName: "".concat(prefixCls, "-").concat(animation)\n };\n }\n if (transitionName) {\n return {\n motionName: transitionName\n };\n }\n return null;\n}\nfunction getWin(ele) {\n return ele.ownerDocument.defaultView;\n}\n\n/**\n * Get all the scrollable parent elements of the element\n * @param ele The element to be detected\n * @param areaOnly Only return the parent which will cut visible area\n */\nfunction collectScroller(ele) {\n var scrollerList = [];\n var current = ele === null || ele === void 0 ? void 0 : ele.parentElement;\n var scrollStyle = [\'hidden\', \'scroll\', \'clip\', \'auto\'];\n while (current) {\n var _getWin$getComputedSt = getWin(current).getComputedStyle(current),\n overflowX = _getWin$getComputedSt.overflowX,\n overflowY = _getWin$getComputedSt.overflowY,\n overflow = _getWin$getComputedSt.overflow;\n if ([overflowX, overflowY, overflow].some(function (o) {\n return scrollStyle.includes(o);\n })) {\n scrollerList.push(current);\n }\n current = current.parentElement;\n }\n return scrollerList;\n}\nfunction toNum(num) {\n var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n return Number.isNaN(num) ? defaultValue : num;\n}\nfunction getPxValue(val) {\n return toNum(parseFloat(val), 0);\n}\n/**\n *\n *\n * **************************************\n * * Border *\n * * ************************** *\n * * * * * *\n * * B * * S * B *\n * * o * * c * o *\n * * r * Content * r * r *\n * * d * * o * d *\n * * e * * l * e *\n * * r ******************** l * r *\n * * * Scroll * *\n * * ************************** *\n * * Border *\n * **************************************\n *\n */\n/**\n * Get visible area of element\n */\nfunction getVisibleArea(initArea, scrollerList) {\n var visibleArea = _objectSpread2({}, initArea);\n (scrollerList || []).forEach(function (ele) {\n if (ele instanceof HTMLBodyElement) {\n return;\n }\n\n // Skip if static position which will not affect visible area\n var _getWin$getComputedSt2 = getWin(ele).getComputedStyle(ele),\n overflow = _getWin$getComputedSt2.overflow,\n overflowClipMargin = _getWin$getComputedSt2.overflowClipMargin,\n borderTopWidth = _getWin$getComputedSt2.borderTopWidth,\n borderBottomWidth = _getWin$getComputedSt2.borderBottomWidth,\n borderLeftWidth = _getWin$getComputedSt2.borderLeftWidth,\n borderRightWidth = _getWin$getComputedSt2.borderRightWidth;\n var eleRect = ele.getBoundingClientRect();\n var eleOutHeight = ele.offsetHeight,\n eleInnerHeight = ele.clientHeight,\n eleOutWidth = ele.offsetWidth,\n eleInnerWidth = ele.clientWidth;\n var borderTopNum = getPxValue(borderTopWidth);\n var borderBottomNum = getPxValue(borderBottomWidth);\n var borderLeftNum = getPxValue(borderLeftWidth);\n var borderRightNum = getPxValue(borderRightWidth);\n var scaleX = toNum(Math.round(eleRect.width / eleOutWidth * 1000) / 1000);\n var scaleY = toNum(Math.round(eleRect.height / eleOutHeight * 1000) / 1000);\n\n // Original visible area\n var eleScrollWidth = (eleOutWidth - eleInnerWidth - borderLeftNum - borderRightNum) * scaleX;\n var eleScrollHeight = (eleOutHeight - eleInnerHeight - borderTopNum - borderBottomNum) * scaleY;\n\n // Cut border size\n var scaledBorderTopWidth = borderTopNum * scaleY;\n var scaledBorderBottomWidth = borderBottomNum * scaleY;\n var scaledBorderLeftWidth = borderLeftNum * scaleX;\n var scaledBorderRightWidth = borderRightNum * scaleX;\n\n // Clip margin\n var clipMarginWidth = 0;\n var clipMarginHeight = 0;\n if (overflow === \'clip\') {\n var clipNum = getPxValue(overflowClipMargin);\n clipMarginWidth = clipNum * scaleX;\n clipMarginHeight = clipNum * scaleY;\n }\n\n // Region\n var eleLeft = eleRect.x + scaledBorderLeftWidth - clipMarginWidth;\n var eleTop = eleRect.y + scaledBorderTopWidth - clipMarginHeight;\n var eleRight = eleLeft + eleRect.width + 2 * clipMarginWidth - scaledBorderLeftWidth - scaledBorderRightWidth - eleScrollWidth;\n var eleBottom = eleTop + eleRect.height + 2 * clipMarginHeight - scaledBorderTopWidth - scaledBorderBottomWidth - eleScrollHeight;\n visibleArea.left = Math.max(visibleArea.left, eleLeft);\n visibleArea.top = Math.max(visibleArea.top, eleTop);\n visibleArea.right = Math.min(visibleArea.right, eleRight);\n visibleArea.bottom = Math.min(visibleArea.bottom, eleBottom);\n });\n return visibleArea;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useAlign.js\n\n\n\n\n\n\n\n\nfunction getUnitOffset(size) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var offsetStr = "".concat(offset);\n var cells = offsetStr.match(/^(.*)\\%$/);\n if (cells) {\n return size * (parseFloat(cells[1]) / 100);\n }\n return parseFloat(offsetStr);\n}\nfunction getNumberOffset(rect, offset) {\n var _ref = offset || [],\n _ref2 = slicedToArray_slicedToArray(_ref, 2),\n offsetX = _ref2[0],\n offsetY = _ref2[1];\n return [getUnitOffset(rect.width, offsetX), getUnitOffset(rect.height, offsetY)];\n}\nfunction splitPoints() {\n var points = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : \'\';\n return [points[0], points[1]];\n}\nfunction getAlignPoint(rect, points) {\n var topBottom = points[0];\n var leftRight = points[1];\n var x;\n var y;\n\n // Top & Bottom\n if (topBottom === \'t\') {\n y = rect.y;\n } else if (topBottom === \'b\') {\n y = rect.y + rect.height;\n } else {\n y = rect.y + rect.height / 2;\n }\n\n // Left & Right\n if (leftRight === \'l\') {\n x = rect.x;\n } else if (leftRight === \'r\') {\n x = rect.x + rect.width;\n } else {\n x = rect.x + rect.width / 2;\n }\n return {\n x: x,\n y: y\n };\n}\nfunction reversePoints(points, index) {\n var reverseMap = {\n t: \'b\',\n b: \'t\',\n l: \'r\',\n r: \'l\'\n };\n return points.map(function (point, i) {\n if (i === index) {\n return reverseMap[point] || \'c\';\n }\n return point;\n }).join(\'\');\n}\nfunction useAlign(open, popupEle, target, placement, builtinPlacements, popupAlign, onPopupAlign) {\n var _React$useState = react.useState({\n ready: false,\n offsetX: 0,\n offsetY: 0,\n arrowX: 0,\n arrowY: 0,\n scaleX: 1,\n scaleY: 1,\n align: builtinPlacements[placement] || {}\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n offsetInfo = _React$useState2[0],\n setOffsetInfo = _React$useState2[1];\n var alignCountRef = react.useRef(0);\n var scrollerList = react.useMemo(function () {\n if (!popupEle) {\n return [];\n }\n return collectScroller(popupEle);\n }, [popupEle]);\n\n // ========================= Flip ==========================\n // We will memo flip info.\n // If size change to make flip, it will memo the flip info and use it in next align.\n var prevFlipRef = react.useRef({});\n var resetFlipCache = function resetFlipCache() {\n prevFlipRef.current = {};\n };\n if (!open) {\n resetFlipCache();\n }\n\n // ========================= Align =========================\n var onAlign = useEvent(function () {\n if (popupEle && target && open) {\n var popupElement = popupEle;\n var originLeft = popupElement.style.left;\n var originTop = popupElement.style.top;\n var doc = popupElement.ownerDocument;\n var win = getWin(popupElement);\n\n // Placement\n var placementInfo = _objectSpread2(_objectSpread2({}, builtinPlacements[placement]), popupAlign);\n\n // Reset first\n popupElement.style.left = \'0\';\n popupElement.style.top = \'0\';\n\n // Calculate align style, we should consider `transform` case\n var targetRect;\n if (Array.isArray(target)) {\n targetRect = {\n x: target[0],\n y: target[1],\n width: 0,\n height: 0\n };\n } else {\n var rect = target.getBoundingClientRect();\n targetRect = {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height\n };\n }\n var popupRect = popupElement.getBoundingClientRect();\n var _win$getComputedStyle = win.getComputedStyle(popupElement),\n width = _win$getComputedStyle.width,\n height = _win$getComputedStyle.height;\n var _doc$documentElement = doc.documentElement,\n clientWidth = _doc$documentElement.clientWidth,\n clientHeight = _doc$documentElement.clientHeight,\n scrollWidth = _doc$documentElement.scrollWidth,\n scrollHeight = _doc$documentElement.scrollHeight,\n scrollTop = _doc$documentElement.scrollTop,\n scrollLeft = _doc$documentElement.scrollLeft;\n var popupHeight = popupRect.height;\n var popupWidth = popupRect.width;\n var targetHeight = targetRect.height;\n var targetWidth = targetRect.width;\n\n // Get bounding of visible area\n var visibleArea = placementInfo.htmlRegion === \'scroll\' ?\n // Scroll region should take scrollLeft & scrollTop into account\n {\n left: -scrollLeft,\n top: -scrollTop,\n right: scrollWidth - scrollLeft,\n bottom: scrollHeight - scrollTop\n } : {\n left: 0,\n top: 0,\n right: clientWidth,\n bottom: clientHeight\n };\n visibleArea = getVisibleArea(visibleArea, scrollerList);\n\n // Reset back\n popupElement.style.left = originLeft;\n popupElement.style.top = originTop;\n\n // Calculate scale\n var _scaleX = toNum(Math.round(popupWidth / parseFloat(width) * 1000) / 1000);\n var _scaleY = toNum(Math.round(popupHeight / parseFloat(height) * 1000) / 1000);\n\n // No need to align since it\'s not visible in view\n if (_scaleX === 0 || _scaleY === 0 || isDOM(target) && !isVisible(target)) {\n return;\n }\n\n // Offset\n var offset = placementInfo.offset,\n targetOffset = placementInfo.targetOffset;\n var _getNumberOffset = getNumberOffset(popupRect, offset),\n _getNumberOffset2 = slicedToArray_slicedToArray(_getNumberOffset, 2),\n popupOffsetX = _getNumberOffset2[0],\n popupOffsetY = _getNumberOffset2[1];\n var _getNumberOffset3 = getNumberOffset(targetRect, targetOffset),\n _getNumberOffset4 = slicedToArray_slicedToArray(_getNumberOffset3, 2),\n targetOffsetX = _getNumberOffset4[0],\n targetOffsetY = _getNumberOffset4[1];\n targetRect.x -= targetOffsetX;\n targetRect.y -= targetOffsetY;\n\n // Points\n var _ref3 = placementInfo.points || [],\n _ref4 = slicedToArray_slicedToArray(_ref3, 2),\n popupPoint = _ref4[0],\n targetPoint = _ref4[1];\n var targetPoints = splitPoints(targetPoint);\n var popupPoints = splitPoints(popupPoint);\n var targetAlignPoint = getAlignPoint(targetRect, targetPoints);\n var popupAlignPoint = getAlignPoint(popupRect, popupPoints);\n\n // Real align info may not same as origin one\n var nextAlignInfo = _objectSpread2({}, placementInfo);\n\n // Next Offset\n var nextOffsetX = targetAlignPoint.x - popupAlignPoint.x + popupOffsetX;\n var nextOffsetY = targetAlignPoint.y - popupAlignPoint.y + popupOffsetY;\n\n // ============== Intersection ===============\n // Get area by position. Used for check if flip area is better\n function getIntersectionVisibleArea(offsetX, offsetY) {\n var l = popupRect.x + offsetX;\n var t = popupRect.y + offsetY;\n var r = l + popupWidth;\n var b = t + popupHeight;\n var visibleL = Math.max(l, visibleArea.left);\n var visibleT = Math.max(t, visibleArea.top);\n var visibleR = Math.min(r, visibleArea.right);\n var visibleB = Math.min(b, visibleArea.bottom);\n return Math.max(0, (visibleR - visibleL) * (visibleB - visibleT));\n }\n var originIntersectionVisibleArea = getIntersectionVisibleArea(nextOffsetX, nextOffsetY);\n\n // ========================== Overflow ===========================\n var targetAlignPointTL = getAlignPoint(targetRect, [\'t\', \'l\']);\n var popupAlignPointTL = getAlignPoint(popupRect, [\'t\', \'l\']);\n var targetAlignPointBR = getAlignPoint(targetRect, [\'b\', \'r\']);\n var popupAlignPointBR = getAlignPoint(popupRect, [\'b\', \'r\']);\n var overflow = placementInfo.overflow || {};\n var adjustX = overflow.adjustX,\n adjustY = overflow.adjustY,\n shiftX = overflow.shiftX,\n shiftY = overflow.shiftY;\n var supportAdjust = function supportAdjust(val) {\n if (typeof val === \'boolean\') {\n return val;\n }\n return val >= 0;\n };\n\n // Prepare position\n var nextPopupY;\n var nextPopupBottom;\n var nextPopupX;\n var nextPopupRight;\n function syncNextPopupPosition() {\n nextPopupY = popupRect.y + nextOffsetY;\n nextPopupBottom = nextPopupY + popupHeight;\n nextPopupX = popupRect.x + nextOffsetX;\n nextPopupRight = nextPopupX + popupWidth;\n }\n syncNextPopupPosition();\n\n // >>>>>>>>>> Top & Bottom\n var needAdjustY = supportAdjust(adjustY);\n var sameTB = popupPoints[0] === targetPoints[0];\n\n // Bottom to Top\n if (needAdjustY && popupPoints[0] === \'t\' && (nextPopupBottom > visibleArea.bottom || prevFlipRef.current.bt)) {\n var tmpNextOffsetY = nextOffsetY;\n if (sameTB) {\n tmpNextOffsetY -= popupHeight - targetHeight;\n } else {\n tmpNextOffsetY = targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;\n }\n if (getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.bt = true;\n nextOffsetY = tmpNextOffsetY;\n nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];\n } else {\n prevFlipRef.current.bt = false;\n }\n }\n\n // Top to Bottom\n if (needAdjustY && popupPoints[0] === \'b\' && (nextPopupY < visibleArea.top || prevFlipRef.current.tb)) {\n var _tmpNextOffsetY = nextOffsetY;\n if (sameTB) {\n _tmpNextOffsetY += popupHeight - targetHeight;\n } else {\n _tmpNextOffsetY = targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;\n }\n if (getIntersectionVisibleArea(nextOffsetX, _tmpNextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.tb = true;\n nextOffsetY = _tmpNextOffsetY;\n nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];\n } else {\n prevFlipRef.current.tb = false;\n }\n }\n\n // >>>>>>>>>> Left & Right\n var needAdjustX = supportAdjust(adjustX);\n\n // >>>>> Flip\n var sameLR = popupPoints[1] === targetPoints[1];\n\n // Right to Left\n if (needAdjustX && popupPoints[1] === \'l\' && (nextPopupRight > visibleArea.right || prevFlipRef.current.rl)) {\n var tmpNextOffsetX = nextOffsetX;\n if (sameLR) {\n tmpNextOffsetX -= popupWidth - targetWidth;\n } else {\n tmpNextOffsetX = targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;\n }\n if (getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.rl = true;\n nextOffsetX = tmpNextOffsetX;\n nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];\n } else {\n prevFlipRef.current.rl = false;\n }\n }\n\n // Left to Right\n if (needAdjustX && popupPoints[1] === \'r\' && (nextPopupX < visibleArea.left || prevFlipRef.current.lr)) {\n var _tmpNextOffsetX = nextOffsetX;\n if (sameLR) {\n _tmpNextOffsetX += popupWidth - targetWidth;\n } else {\n _tmpNextOffsetX = targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;\n }\n if (getIntersectionVisibleArea(_tmpNextOffsetX, nextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.lr = true;\n nextOffsetX = _tmpNextOffsetX;\n nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];\n } else {\n prevFlipRef.current.lr = false;\n }\n }\n\n // ============================ Shift ============================\n syncNextPopupPosition();\n var numShiftX = shiftX === true ? 0 : shiftX;\n if (typeof numShiftX === \'number\') {\n // Left\n if (nextPopupX < visibleArea.left) {\n nextOffsetX -= nextPopupX - visibleArea.left;\n if (targetRect.x + targetWidth < visibleArea.left + numShiftX) {\n nextOffsetX += targetRect.x - visibleArea.left + targetWidth - numShiftX;\n }\n }\n\n // Right\n if (nextPopupRight > visibleArea.right) {\n nextOffsetX -= nextPopupRight - visibleArea.right;\n if (targetRect.x > visibleArea.right - numShiftX) {\n nextOffsetX += targetRect.x - visibleArea.right + numShiftX;\n }\n }\n }\n var numShiftY = shiftY === true ? 0 : shiftY;\n if (typeof numShiftY === \'number\') {\n // Top\n if (nextPopupY < visibleArea.top) {\n nextOffsetY -= nextPopupY - visibleArea.top;\n if (targetRect.y + targetHeight < visibleArea.top + numShiftY) {\n nextOffsetY += targetRect.y - visibleArea.top + targetHeight - numShiftY;\n }\n }\n\n // Bottom\n if (nextPopupBottom > visibleArea.bottom) {\n nextOffsetY -= nextPopupBottom - visibleArea.bottom;\n if (targetRect.y > visibleArea.bottom - numShiftY) {\n nextOffsetY += targetRect.y - visibleArea.bottom + numShiftY;\n }\n }\n }\n\n // ============================ Arrow ============================\n // Arrow center align\n var popupLeft = popupRect.x + nextOffsetX;\n var popupRight = popupLeft + popupWidth;\n var popupTop = popupRect.y + nextOffsetY;\n var popupBottom = popupTop + popupHeight;\n var targetLeft = targetRect.x;\n var targetRight = targetLeft + targetWidth;\n var targetTop = targetRect.y;\n var targetBottom = targetTop + targetHeight;\n var maxLeft = Math.max(popupLeft, targetLeft);\n var minRight = Math.min(popupRight, targetRight);\n var xCenter = (maxLeft + minRight) / 2;\n var nextArrowX = xCenter - popupLeft;\n var maxTop = Math.max(popupTop, targetTop);\n var minBottom = Math.min(popupBottom, targetBottom);\n var yCenter = (maxTop + minBottom) / 2;\n var nextArrowY = yCenter - popupTop;\n onPopupAlign === null || onPopupAlign === void 0 ? void 0 : onPopupAlign(popupEle, nextAlignInfo);\n setOffsetInfo({\n ready: true,\n offsetX: nextOffsetX / _scaleX,\n offsetY: nextOffsetY / _scaleY,\n arrowX: nextArrowX / _scaleX,\n arrowY: nextArrowY / _scaleY,\n scaleX: _scaleX,\n scaleY: _scaleY,\n align: nextAlignInfo\n });\n }\n });\n var triggerAlign = function triggerAlign() {\n alignCountRef.current += 1;\n var id = alignCountRef.current;\n\n // Merge all align requirement into one frame\n Promise.resolve().then(function () {\n if (alignCountRef.current === id) {\n onAlign();\n }\n });\n };\n\n // Reset ready status when placement & open changed\n var resetReady = function resetReady() {\n setOffsetInfo(function (ori) {\n return _objectSpread2(_objectSpread2({}, ori), {}, {\n ready: false\n });\n });\n };\n hooks_useLayoutEffect(resetReady, [placement]);\n hooks_useLayoutEffect(function () {\n if (!open) {\n resetReady();\n }\n }, [open]);\n return [offsetInfo.ready, offsetInfo.offsetX, offsetInfo.offsetY, offsetInfo.arrowX, offsetInfo.arrowY, offsetInfo.scaleX, offsetInfo.scaleY, offsetInfo.align, triggerAlign];\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useWatch.js\n\n\n\nfunction useWatch(open, target, popup, onAlign) {\n hooks_useLayoutEffect(function () {\n if (open && target && popup) {\n var targetElement = target;\n var popupElement = popup;\n var targetScrollList = collectScroller(targetElement);\n var popupScrollList = collectScroller(popupElement);\n var win = getWin(popupElement);\n var mergedList = new Set([win].concat(_toConsumableArray(targetScrollList), _toConsumableArray(popupScrollList)));\n function notifyScroll() {\n onAlign();\n }\n mergedList.forEach(function (scroller) {\n scroller.addEventListener(\'scroll\', notifyScroll, {\n passive: true\n });\n });\n win.addEventListener(\'resize\', notifyScroll, {\n passive: true\n });\n\n // First time always do align\n onAlign();\n return function () {\n mergedList.forEach(function (scroller) {\n scroller.removeEventListener(\'scroll\', notifyScroll);\n win.removeEventListener(\'resize\', notifyScroll);\n });\n };\n }\n }, [open, target, popup]);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/context.js\n\nvar context_excluded = (/* unused pure expression or super */ null && (["children"]));\n\nvar context_Context = /*#__PURE__*/react.createContext({});\nfunction MotionProvider(_ref) {\n var children = _ref.children,\n props = _objectWithoutProperties(_ref, context_excluded);\n return /*#__PURE__*/React.createElement(context_Context.Provider, {\n value: props\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/DomWrapper.js\n\n\n\n\n\nvar DomWrapper_DomWrapper = /*#__PURE__*/function (_React$Component) {\n _inherits(DomWrapper, _React$Component);\n var _super = _createSuper(DomWrapper);\n function DomWrapper() {\n classCallCheck_classCallCheck(this, DomWrapper);\n return _super.apply(this, arguments);\n }\n createClass_createClass(DomWrapper, [{\n key: "render",\n value: function render() {\n return this.props.children;\n }\n }]);\n return DomWrapper;\n}(react.Component);\n/* harmony default export */ const es_DomWrapper = (DomWrapper_DomWrapper);\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/interface.js\nvar STATUS_NONE = \'none\';\nvar STATUS_APPEAR = \'appear\';\nvar STATUS_ENTER = \'enter\';\nvar STATUS_LEAVE = \'leave\';\nvar STEP_NONE = \'none\';\nvar STEP_PREPARE = \'prepare\';\nvar STEP_START = \'start\';\nvar STEP_ACTIVE = \'active\';\nvar STEP_ACTIVATED = \'end\';\n/**\n * Used for disabled motion case.\n * Prepare stage will still work but start & active will be skipped.\n */\nvar STEP_PREPARED = \'prepared\';\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/util/motion.js\n\n\n// ================= Transition =================\n// Event wrapper. Copy from react source code\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes["Webkit".concat(styleProp)] = "webkit".concat(eventName);\n prefixes["Moz".concat(styleProp)] = "moz".concat(eventName);\n prefixes["ms".concat(styleProp)] = "MS".concat(eventName);\n prefixes["O".concat(styleProp)] = "o".concat(eventName.toLowerCase());\n return prefixes;\n}\nfunction getVendorPrefixes(domSupport, win) {\n var prefixes = {\n animationend: makePrefixMap(\'Animation\', \'AnimationEnd\'),\n transitionend: makePrefixMap(\'Transition\', \'TransitionEnd\')\n };\n if (domSupport) {\n if (!(\'AnimationEvent\' in win)) {\n delete prefixes.animationend.animation;\n }\n if (!(\'TransitionEvent\' in win)) {\n delete prefixes.transitionend.transition;\n }\n }\n return prefixes;\n}\nvar vendorPrefixes = getVendorPrefixes(canUseDom(), typeof window !== \'undefined\' ? window : {});\nvar style = {};\nif (canUseDom()) {\n var _document$createEleme = document.createElement(\'div\');\n style = _document$createEleme.style;\n}\nvar prefixedEventNames = {};\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) {\n return prefixedEventNames[eventName];\n }\n var prefixMap = vendorPrefixes[eventName];\n if (prefixMap) {\n var stylePropList = Object.keys(prefixMap);\n var len = stylePropList.length;\n for (var i = 0; i < len; i += 1) {\n var styleProp = stylePropList[i];\n if (Object.prototype.hasOwnProperty.call(prefixMap, styleProp) && styleProp in style) {\n prefixedEventNames[eventName] = prefixMap[styleProp];\n return prefixedEventNames[eventName];\n }\n }\n }\n return \'\';\n}\nvar internalAnimationEndName = getVendorPrefixedEventName(\'animationend\');\nvar internalTransitionEndName = getVendorPrefixedEventName(\'transitionend\');\nvar supportTransition = !!(internalAnimationEndName && internalTransitionEndName);\nvar animationEndName = internalAnimationEndName || \'animationend\';\nvar transitionEndName = internalTransitionEndName || \'transitionend\';\nfunction getTransitionName(transitionName, transitionType) {\n if (!transitionName) return null;\n if (typeof_typeof(transitionName) === \'object\') {\n var type = transitionType.replace(/-\\w/g, function (match) {\n return match[1].toUpperCase();\n });\n return transitionName[type];\n }\n return "".concat(transitionName, "-").concat(transitionType);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useDomMotionEvents.js\n\n\n\n/* harmony default export */ const useDomMotionEvents = (function (callback) {\n var cacheElementRef = (0,react.useRef)();\n\n // Cache callback\n var callbackRef = (0,react.useRef)(callback);\n callbackRef.current = callback;\n\n // Internal motion event handler\n var onInternalMotionEnd = react.useCallback(function (event) {\n callbackRef.current(event);\n }, []);\n\n // Remove events\n function removeMotionEvents(element) {\n if (element) {\n element.removeEventListener(transitionEndName, onInternalMotionEnd);\n element.removeEventListener(animationEndName, onInternalMotionEnd);\n }\n }\n\n // Patch events\n function patchMotionEvents(element) {\n if (cacheElementRef.current && cacheElementRef.current !== element) {\n removeMotionEvents(cacheElementRef.current);\n }\n if (element && element !== cacheElementRef.current) {\n element.addEventListener(transitionEndName, onInternalMotionEnd);\n element.addEventListener(animationEndName, onInternalMotionEnd);\n\n // Save as cache in case dom removed trigger by `motionDeadline`\n cacheElementRef.current = element;\n }\n }\n\n // Clean up when removed\n react.useEffect(function () {\n return function () {\n removeMotionEvents(cacheElementRef.current);\n };\n }, []);\n return [patchMotionEvents, removeMotionEvents];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useIsomorphicLayoutEffect.js\n\n\n\n// It\'s safe to use `useLayoutEffect` but the warning is annoying\nvar useIsomorphicLayoutEffect = canUseDom() ? react.useLayoutEffect : react.useEffect;\n/* harmony default export */ const hooks_useIsomorphicLayoutEffect = (useIsomorphicLayoutEffect);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/raf.js\nvar raf_raf = function raf(callback) {\n return +setTimeout(callback, 16);\n};\nvar caf = function caf(num) {\n return clearTimeout(num);\n};\nif (typeof window !== \'undefined\' && \'requestAnimationFrame\' in window) {\n raf_raf = function raf(callback) {\n return window.requestAnimationFrame(callback);\n };\n caf = function caf(handle) {\n return window.cancelAnimationFrame(handle);\n };\n}\nvar rafUUID = 0;\nvar rafIds = new Map();\nfunction cleanup(id) {\n rafIds.delete(id);\n}\nvar wrapperRaf = function wrapperRaf(callback) {\n var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n rafUUID += 1;\n var id = rafUUID;\n function callRef(leftTimes) {\n if (leftTimes === 0) {\n // Clean up\n cleanup(id);\n\n // Trigger\n callback();\n } else {\n // Next raf\n var realId = raf_raf(function () {\n callRef(leftTimes - 1);\n });\n\n // Bind real raf id\n rafIds.set(id, realId);\n }\n }\n callRef(times);\n return id;\n};\nwrapperRaf.cancel = function (id) {\n var realId = rafIds.get(id);\n cleanup(realId);\n return caf(realId);\n};\n/* harmony default export */ const es_raf = (wrapperRaf);\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useNextFrame.js\n\n\n/* harmony default export */ const useNextFrame = (function () {\n var nextFrameRef = react.useRef(null);\n function cancelNextFrame() {\n es_raf.cancel(nextFrameRef.current);\n }\n function nextFrame(callback) {\n var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;\n cancelNextFrame();\n var nextFrameId = es_raf(function () {\n if (delay <= 1) {\n callback({\n isCanceled: function isCanceled() {\n return nextFrameId !== nextFrameRef.current;\n }\n });\n } else {\n nextFrame(callback, delay - 1);\n }\n });\n nextFrameRef.current = nextFrameId;\n }\n react.useEffect(function () {\n return function () {\n cancelNextFrame();\n };\n }, []);\n return [nextFrame, cancelNextFrame];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useStepQueue.js\n\n\n\n\n\n\nvar FULL_STEP_QUEUE = [STEP_PREPARE, STEP_START, STEP_ACTIVE, STEP_ACTIVATED];\nvar SIMPLE_STEP_QUEUE = [STEP_PREPARE, STEP_PREPARED];\n\n/** Skip current step */\nvar SkipStep = false;\n/** Current step should be update in */\nvar DoStep = true;\nfunction isActive(step) {\n return step === STEP_ACTIVE || step === STEP_ACTIVATED;\n}\n/* harmony default export */ const useStepQueue = (function (status, prepareOnly, callback) {\n var _useState = useSafeState(STEP_NONE),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n step = _useState2[0],\n setStep = _useState2[1];\n var _useNextFrame = useNextFrame(),\n _useNextFrame2 = slicedToArray_slicedToArray(_useNextFrame, 2),\n nextFrame = _useNextFrame2[0],\n cancelNextFrame = _useNextFrame2[1];\n function startQueue() {\n setStep(STEP_PREPARE, true);\n }\n var STEP_QUEUE = prepareOnly ? SIMPLE_STEP_QUEUE : FULL_STEP_QUEUE;\n hooks_useIsomorphicLayoutEffect(function () {\n if (step !== STEP_NONE && step !== STEP_ACTIVATED) {\n var index = STEP_QUEUE.indexOf(step);\n var nextStep = STEP_QUEUE[index + 1];\n var result = callback(step);\n if (result === SkipStep) {\n // Skip when no needed\n setStep(nextStep, true);\n } else if (nextStep) {\n // Do as frame for step update\n nextFrame(function (info) {\n function doNext() {\n // Skip since current queue is ood\n if (info.isCanceled()) return;\n setStep(nextStep, true);\n }\n if (result === true) {\n doNext();\n } else {\n // Only promise should be async\n Promise.resolve(result).then(doNext);\n }\n });\n }\n }\n }, [status, step]);\n react.useEffect(function () {\n return function () {\n cancelNextFrame();\n };\n }, []);\n return [startQueue, step];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useStatus.js\n\n\n\n\n\n\n\n\n\n\nfunction useStatus(supportMotion, visible, getElement, _ref) {\n var _ref$motionEnter = _ref.motionEnter,\n motionEnter = _ref$motionEnter === void 0 ? true : _ref$motionEnter,\n _ref$motionAppear = _ref.motionAppear,\n motionAppear = _ref$motionAppear === void 0 ? true : _ref$motionAppear,\n _ref$motionLeave = _ref.motionLeave,\n motionLeave = _ref$motionLeave === void 0 ? true : _ref$motionLeave,\n motionDeadline = _ref.motionDeadline,\n motionLeaveImmediately = _ref.motionLeaveImmediately,\n onAppearPrepare = _ref.onAppearPrepare,\n onEnterPrepare = _ref.onEnterPrepare,\n onLeavePrepare = _ref.onLeavePrepare,\n onAppearStart = _ref.onAppearStart,\n onEnterStart = _ref.onEnterStart,\n onLeaveStart = _ref.onLeaveStart,\n onAppearActive = _ref.onAppearActive,\n onEnterActive = _ref.onEnterActive,\n onLeaveActive = _ref.onLeaveActive,\n onAppearEnd = _ref.onAppearEnd,\n onEnterEnd = _ref.onEnterEnd,\n onLeaveEnd = _ref.onLeaveEnd,\n onVisibleChanged = _ref.onVisibleChanged;\n // Used for outer render usage to avoid `visible: false & status: none` to render nothing\n var _useState = useSafeState(),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n asyncVisible = _useState2[0],\n setAsyncVisible = _useState2[1];\n var _useState3 = useSafeState(STATUS_NONE),\n _useState4 = slicedToArray_slicedToArray(_useState3, 2),\n status = _useState4[0],\n setStatus = _useState4[1];\n var _useState5 = useSafeState(null),\n _useState6 = slicedToArray_slicedToArray(_useState5, 2),\n style = _useState6[0],\n setStyle = _useState6[1];\n var mountedRef = (0,react.useRef)(false);\n var deadlineRef = (0,react.useRef)(null);\n\n // =========================== Dom Node ===========================\n function getDomElement() {\n return getElement();\n }\n\n // ========================== Motion End ==========================\n var activeRef = (0,react.useRef)(false);\n\n /**\n * Clean up status & style\n */\n function updateMotionEndStatus() {\n setStatus(STATUS_NONE, true);\n setStyle(null, true);\n }\n function onInternalMotionEnd(event) {\n var element = getDomElement();\n if (event && !event.deadline && event.target !== element) {\n // event exists\n // not initiated by deadline\n // transitionEnd not fired by inner elements\n return;\n }\n var currentActive = activeRef.current;\n var canEnd;\n if (status === STATUS_APPEAR && currentActive) {\n canEnd = onAppearEnd === null || onAppearEnd === void 0 ? void 0 : onAppearEnd(element, event);\n } else if (status === STATUS_ENTER && currentActive) {\n canEnd = onEnterEnd === null || onEnterEnd === void 0 ? void 0 : onEnterEnd(element, event);\n } else if (status === STATUS_LEAVE && currentActive) {\n canEnd = onLeaveEnd === null || onLeaveEnd === void 0 ? void 0 : onLeaveEnd(element, event);\n }\n\n // Only update status when `canEnd` and not destroyed\n if (status !== STATUS_NONE && currentActive && canEnd !== false) {\n updateMotionEndStatus();\n }\n }\n var _useDomMotionEvents = useDomMotionEvents(onInternalMotionEnd),\n _useDomMotionEvents2 = slicedToArray_slicedToArray(_useDomMotionEvents, 1),\n patchMotionEvents = _useDomMotionEvents2[0];\n\n // ============================= Step =============================\n var getEventHandlers = function getEventHandlers(targetStatus) {\n var _ref2, _ref3, _ref4;\n switch (targetStatus) {\n case STATUS_APPEAR:\n return _ref2 = {}, _defineProperty(_ref2, STEP_PREPARE, onAppearPrepare), _defineProperty(_ref2, STEP_START, onAppearStart), _defineProperty(_ref2, STEP_ACTIVE, onAppearActive), _ref2;\n case STATUS_ENTER:\n return _ref3 = {}, _defineProperty(_ref3, STEP_PREPARE, onEnterPrepare), _defineProperty(_ref3, STEP_START, onEnterStart), _defineProperty(_ref3, STEP_ACTIVE, onEnterActive), _ref3;\n case STATUS_LEAVE:\n return _ref4 = {}, _defineProperty(_ref4, STEP_PREPARE, onLeavePrepare), _defineProperty(_ref4, STEP_START, onLeaveStart), _defineProperty(_ref4, STEP_ACTIVE, onLeaveActive), _ref4;\n default:\n return {};\n }\n };\n var eventHandlers = react.useMemo(function () {\n return getEventHandlers(status);\n }, [status]);\n var _useStepQueue = useStepQueue(status, !supportMotion, function (newStep) {\n // Only prepare step can be skip\n if (newStep === STEP_PREPARE) {\n var onPrepare = eventHandlers[STEP_PREPARE];\n if (!onPrepare) {\n return SkipStep;\n }\n return onPrepare(getDomElement());\n }\n\n // Rest step is sync update\n if (step in eventHandlers) {\n var _eventHandlers$step;\n setStyle(((_eventHandlers$step = eventHandlers[step]) === null || _eventHandlers$step === void 0 ? void 0 : _eventHandlers$step.call(eventHandlers, getDomElement(), null)) || null);\n }\n if (step === STEP_ACTIVE) {\n // Patch events when motion needed\n patchMotionEvents(getDomElement());\n if (motionDeadline > 0) {\n clearTimeout(deadlineRef.current);\n deadlineRef.current = setTimeout(function () {\n onInternalMotionEnd({\n deadline: true\n });\n }, motionDeadline);\n }\n }\n if (step === STEP_PREPARED) {\n updateMotionEndStatus();\n }\n return DoStep;\n }),\n _useStepQueue2 = slicedToArray_slicedToArray(_useStepQueue, 2),\n startStep = _useStepQueue2[0],\n step = _useStepQueue2[1];\n var active = isActive(step);\n activeRef.current = active;\n\n // ============================ Status ============================\n // Update with new status\n hooks_useIsomorphicLayoutEffect(function () {\n setAsyncVisible(visible);\n var isMounted = mountedRef.current;\n mountedRef.current = true;\n\n // if (!supportMotion) {\n // return;\n // }\n\n var nextStatus;\n\n // Appear\n if (!isMounted && visible && motionAppear) {\n nextStatus = STATUS_APPEAR;\n }\n\n // Enter\n if (isMounted && visible && motionEnter) {\n nextStatus = STATUS_ENTER;\n }\n\n // Leave\n if (isMounted && !visible && motionLeave || !isMounted && motionLeaveImmediately && !visible && motionLeave) {\n nextStatus = STATUS_LEAVE;\n }\n var nextEventHandlers = getEventHandlers(nextStatus);\n\n // Update to next status\n if (nextStatus && (supportMotion || nextEventHandlers[STEP_PREPARE])) {\n setStatus(nextStatus);\n startStep();\n } else {\n // Set back in case no motion but prev status has prepare step\n setStatus(STATUS_NONE);\n }\n }, [visible]);\n\n // ============================ Effect ============================\n // Reset when motion changed\n (0,react.useEffect)(function () {\n if (\n // Cancel appear\n status === STATUS_APPEAR && !motionAppear ||\n // Cancel enter\n status === STATUS_ENTER && !motionEnter ||\n // Cancel leave\n status === STATUS_LEAVE && !motionLeave) {\n setStatus(STATUS_NONE);\n }\n }, [motionAppear, motionEnter, motionLeave]);\n (0,react.useEffect)(function () {\n return function () {\n mountedRef.current = false;\n clearTimeout(deadlineRef.current);\n };\n }, []);\n\n // Trigger `onVisibleChanged`\n var firstMountChangeRef = react.useRef(false);\n (0,react.useEffect)(function () {\n // [visible & motion not end] => [!visible & motion end] still need trigger onVisibleChanged\n if (asyncVisible) {\n firstMountChangeRef.current = true;\n }\n if (asyncVisible !== undefined && status === STATUS_NONE) {\n // Skip first render is invisible since it\'s nothing changed\n if (firstMountChangeRef.current || asyncVisible) {\n onVisibleChanged === null || onVisibleChanged === void 0 ? void 0 : onVisibleChanged(asyncVisible);\n }\n firstMountChangeRef.current = true;\n }\n }, [asyncVisible, status]);\n\n // ============================ Styles ============================\n var mergedStyle = style;\n if (eventHandlers[STEP_PREPARE] && step === STEP_START) {\n mergedStyle = _objectSpread2({\n transition: \'none\'\n }, mergedStyle);\n }\n return [status, step, mergedStyle, asyncVisible !== null && asyncVisible !== void 0 ? asyncVisible : visible];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/CSSMotion.js\n\n\n\n\n/* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * `transitionSupport` is used for none transition test case.\n * Default we use browser transition event support check.\n */\nfunction genCSSMotion(config) {\n var transitionSupport = config;\n if (typeof_typeof(config) === \'object\') {\n transitionSupport = config.transitionSupport;\n }\n function isSupportTransition(props, contextMotion) {\n return !!(props.motionName && transitionSupport && contextMotion !== false);\n }\n var CSSMotion = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _props$visible = props.visible,\n visible = _props$visible === void 0 ? true : _props$visible,\n _props$removeOnLeave = props.removeOnLeave,\n removeOnLeave = _props$removeOnLeave === void 0 ? true : _props$removeOnLeave,\n forceRender = props.forceRender,\n children = props.children,\n motionName = props.motionName,\n leavedClassName = props.leavedClassName,\n eventProps = props.eventProps;\n var _React$useContext = react.useContext(context_Context),\n contextMotion = _React$useContext.motion;\n var supportMotion = isSupportTransition(props, contextMotion);\n\n // Ref to the react node, it may be a HTMLElement\n var nodeRef = (0,react.useRef)();\n // Ref to the dom wrapper in case ref can not pass to HTMLElement\n var wrapperNodeRef = (0,react.useRef)();\n function getDomElement() {\n try {\n // Here we\'re avoiding call for findDOMNode since it\'s deprecated\n // in strict mode. We\'re calling it only when node ref is not\n // an instance of DOM HTMLElement. Otherwise use\n // findDOMNode as a final resort\n return nodeRef.current instanceof HTMLElement ? nodeRef.current : findDOMNode(wrapperNodeRef.current);\n } catch (e) {\n // Only happen when `motionDeadline` trigger but element removed.\n return null;\n }\n }\n var _useStatus = useStatus(supportMotion, visible, getDomElement, props),\n _useStatus2 = slicedToArray_slicedToArray(_useStatus, 4),\n status = _useStatus2[0],\n statusStep = _useStatus2[1],\n statusStyle = _useStatus2[2],\n mergedVisible = _useStatus2[3];\n\n // Record whether content has rendered\n // Will return null for un-rendered even when `removeOnLeave={false}`\n var renderedRef = react.useRef(mergedVisible);\n if (mergedVisible) {\n renderedRef.current = true;\n }\n\n // ====================== Refs ======================\n var setNodeRef = react.useCallback(function (node) {\n nodeRef.current = node;\n fillRef(ref, node);\n }, [ref]);\n\n // ===================== Render =====================\n var motionChildren;\n var mergedProps = _objectSpread2(_objectSpread2({}, eventProps), {}, {\n visible: visible\n });\n if (!children) {\n // No children\n motionChildren = null;\n } else if (status === STATUS_NONE) {\n // Stable children\n if (mergedVisible) {\n motionChildren = children(_objectSpread2({}, mergedProps), setNodeRef);\n } else if (!removeOnLeave && renderedRef.current && leavedClassName) {\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n className: leavedClassName\n }), setNodeRef);\n } else if (forceRender || !removeOnLeave && !leavedClassName) {\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n style: {\n display: \'none\'\n }\n }), setNodeRef);\n } else {\n motionChildren = null;\n }\n } else {\n var _classNames;\n // In motion\n var statusSuffix;\n if (statusStep === STEP_PREPARE) {\n statusSuffix = \'prepare\';\n } else if (isActive(statusStep)) {\n statusSuffix = \'active\';\n } else if (statusStep === STEP_START) {\n statusSuffix = \'start\';\n }\n var motionCls = getTransitionName(motionName, "".concat(status, "-").concat(statusSuffix));\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n className: classnames_default()(getTransitionName(motionName, status), (_classNames = {}, _defineProperty(_classNames, motionCls, motionCls && statusSuffix), _defineProperty(_classNames, motionName, typeof motionName === \'string\'), _classNames)),\n style: statusStyle\n }), setNodeRef);\n }\n\n // Auto inject ref if child node not have `ref` props\n if ( /*#__PURE__*/react.isValidElement(motionChildren) && supportRef(motionChildren)) {\n var _ref = motionChildren,\n originNodeRef = _ref.ref;\n if (!originNodeRef) {\n motionChildren = /*#__PURE__*/react.cloneElement(motionChildren, {\n ref: setNodeRef\n });\n }\n }\n return /*#__PURE__*/react.createElement(es_DomWrapper, {\n ref: wrapperNodeRef\n }, motionChildren);\n });\n CSSMotion.displayName = \'CSSMotion\';\n return CSSMotion;\n}\n/* harmony default export */ const es_CSSMotion = (genCSSMotion(supportTransition));\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/util/diff.js\n\n\nvar STATUS_ADD = \'add\';\nvar STATUS_KEEP = \'keep\';\nvar STATUS_REMOVE = \'remove\';\nvar STATUS_REMOVED = \'removed\';\nfunction wrapKeyToObject(key) {\n var keyObj;\n if (key && typeof_typeof(key) === \'object\' && \'key\' in key) {\n keyObj = key;\n } else {\n keyObj = {\n key: key\n };\n }\n return _objectSpread2(_objectSpread2({}, keyObj), {}, {\n key: String(keyObj.key)\n });\n}\nfunction parseKeys() {\n var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return keys.map(wrapKeyToObject);\n}\nfunction diffKeys() {\n var prevKeys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var currentKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n var list = [];\n var currentIndex = 0;\n var currentLen = currentKeys.length;\n var prevKeyObjects = parseKeys(prevKeys);\n var currentKeyObjects = parseKeys(currentKeys);\n\n // Check prev keys to insert or keep\n prevKeyObjects.forEach(function (keyObj) {\n var hit = false;\n for (var i = currentIndex; i < currentLen; i += 1) {\n var currentKeyObj = currentKeyObjects[i];\n if (currentKeyObj.key === keyObj.key) {\n // New added keys should add before current key\n if (currentIndex < i) {\n list = list.concat(currentKeyObjects.slice(currentIndex, i).map(function (obj) {\n return _objectSpread2(_objectSpread2({}, obj), {}, {\n status: STATUS_ADD\n });\n }));\n currentIndex = i;\n }\n list.push(_objectSpread2(_objectSpread2({}, currentKeyObj), {}, {\n status: STATUS_KEEP\n }));\n currentIndex += 1;\n hit = true;\n break;\n }\n }\n\n // If not hit, it means key is removed\n if (!hit) {\n list.push(_objectSpread2(_objectSpread2({}, keyObj), {}, {\n status: STATUS_REMOVE\n }));\n }\n });\n\n // Add rest to the list\n if (currentIndex < currentLen) {\n list = list.concat(currentKeyObjects.slice(currentIndex).map(function (obj) {\n return _objectSpread2(_objectSpread2({}, obj), {}, {\n status: STATUS_ADD\n });\n }));\n }\n\n /**\n * Merge same key when it remove and add again:\n * [1 - add, 2 - keep, 1 - remove] -> [1 - keep, 2 - keep]\n */\n var keys = {};\n list.forEach(function (_ref) {\n var key = _ref.key;\n keys[key] = (keys[key] || 0) + 1;\n });\n var duplicatedKeys = Object.keys(keys).filter(function (key) {\n return keys[key] > 1;\n });\n duplicatedKeys.forEach(function (matchKey) {\n // Remove `STATUS_REMOVE` node.\n list = list.filter(function (_ref2) {\n var key = _ref2.key,\n status = _ref2.status;\n return key !== matchKey || status !== STATUS_REMOVE;\n });\n\n // Update `STATUS_ADD` to `STATUS_KEEP`\n list.forEach(function (node) {\n if (node.key === matchKey) {\n // eslint-disable-next-line no-param-reassign\n node.status = STATUS_KEEP;\n }\n });\n });\n return list;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/CSSMotionList.js\n\n\n\n\n\n\n\n\n\nvar CSSMotionList_excluded = ["component", "children", "onVisibleChanged", "onAllRemoved"],\n _excluded2 = ["status"];\n/* eslint react/prop-types: 0 */\n\n\n\n\nvar MOTION_PROP_NAMES = [\'eventProps\', \'visible\', \'children\', \'motionName\', \'motionAppear\', \'motionEnter\', \'motionLeave\', \'motionLeaveImmediately\', \'motionDeadline\', \'removeOnLeave\', \'leavedClassName\', \'onAppearStart\', \'onAppearActive\', \'onAppearEnd\', \'onEnterStart\', \'onEnterActive\', \'onEnterEnd\', \'onLeaveStart\', \'onLeaveActive\', \'onLeaveEnd\'];\n/**\n * Generate a CSSMotionList component with config\n * @param transitionSupport No need since CSSMotionList no longer depends on transition support\n * @param CSSMotion CSSMotion component\n */\nfunction genCSSMotionList(transitionSupport) {\n var CSSMotion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : es_CSSMotion;\n var CSSMotionList = /*#__PURE__*/function (_React$Component) {\n _inherits(CSSMotionList, _React$Component);\n var _super = _createSuper(CSSMotionList);\n function CSSMotionList() {\n var _this;\n classCallCheck_classCallCheck(this, CSSMotionList);\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n _this = _super.call.apply(_super, [this].concat(args));\n _defineProperty(_assertThisInitialized(_this), "state", {\n keyEntities: []\n });\n _defineProperty(_assertThisInitialized(_this), "removeKey", function (removeKey) {\n var keyEntities = _this.state.keyEntities;\n var nextKeyEntities = keyEntities.map(function (entity) {\n if (entity.key !== removeKey) return entity;\n return _objectSpread2(_objectSpread2({}, entity), {}, {\n status: STATUS_REMOVED\n });\n });\n _this.setState({\n keyEntities: nextKeyEntities\n });\n return nextKeyEntities.filter(function (_ref) {\n var status = _ref.status;\n return status !== STATUS_REMOVED;\n }).length;\n });\n return _this;\n }\n createClass_createClass(CSSMotionList, [{\n key: "render",\n value: function render() {\n var _this2 = this;\n var keyEntities = this.state.keyEntities;\n var _this$props = this.props,\n component = _this$props.component,\n children = _this$props.children,\n _onVisibleChanged = _this$props.onVisibleChanged,\n onAllRemoved = _this$props.onAllRemoved,\n restProps = objectWithoutProperties_objectWithoutProperties(_this$props, CSSMotionList_excluded);\n var Component = component || react.Fragment;\n var motionProps = {};\n MOTION_PROP_NAMES.forEach(function (prop) {\n motionProps[prop] = restProps[prop];\n delete restProps[prop];\n });\n delete restProps.keys;\n return /*#__PURE__*/react.createElement(Component, restProps, keyEntities.map(function (_ref2) {\n var status = _ref2.status,\n eventProps = objectWithoutProperties_objectWithoutProperties(_ref2, _excluded2);\n var visible = status === STATUS_ADD || status === STATUS_KEEP;\n return /*#__PURE__*/react.createElement(CSSMotion, extends_extends({}, motionProps, {\n key: eventProps.key,\n visible: visible,\n eventProps: eventProps,\n onVisibleChanged: function onVisibleChanged(changedVisible) {\n _onVisibleChanged === null || _onVisibleChanged === void 0 ? void 0 : _onVisibleChanged(changedVisible, {\n key: eventProps.key\n });\n if (!changedVisible) {\n var restKeysCount = _this2.removeKey(eventProps.key);\n if (restKeysCount === 0 && onAllRemoved) {\n onAllRemoved();\n }\n }\n }\n }), children);\n }));\n }\n }], [{\n key: "getDerivedStateFromProps",\n value: function getDerivedStateFromProps(_ref3, _ref4) {\n var keys = _ref3.keys;\n var keyEntities = _ref4.keyEntities;\n var parsedKeyObjects = parseKeys(keys);\n var mixedKeyEntities = diffKeys(keyEntities, parsedKeyObjects);\n return {\n keyEntities: mixedKeyEntities.filter(function (entity) {\n var prevEntity = keyEntities.find(function (_ref5) {\n var key = _ref5.key;\n return entity.key === key;\n });\n\n // Remove if already mark as removed\n if (prevEntity && prevEntity.status === STATUS_REMOVED && entity.status === STATUS_REMOVE) {\n return false;\n }\n return true;\n })\n };\n }\n\n // ZombieJ: Return the count of rest keys. It\'s safe to refactor if need more info.\n }]);\n return CSSMotionList;\n }(react.Component);\n _defineProperty(CSSMotionList, "defaultProps", {\n component: \'div\'\n });\n return CSSMotionList;\n}\n/* harmony default export */ const CSSMotionList = (genCSSMotionList(supportTransition));\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/index.js\n\n\n\n\n/* harmony default export */ const rc_motion_es = (es_CSSMotion);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/Arrow.js\n\n\nfunction Arrow(props) {\n var prefixCls = props.prefixCls,\n align = props.align,\n arrow = props.arrow,\n arrowPos = props.arrowPos;\n var _ref = arrow || {},\n className = _ref.className,\n content = _ref.content;\n var _arrowPos$x = arrowPos.x,\n x = _arrowPos$x === void 0 ? 0 : _arrowPos$x,\n _arrowPos$y = arrowPos.y,\n y = _arrowPos$y === void 0 ? 0 : _arrowPos$y;\n var arrowRef = react.useRef();\n\n // Skip if no align\n if (!align || !align.points) {\n return null;\n }\n var alignStyle = {\n position: \'absolute\'\n };\n\n // Skip if no need to align\n if (align.autoArrow !== false) {\n var popupPoints = align.points[0];\n var targetPoints = align.points[1];\n var popupTB = popupPoints[0];\n var popupLR = popupPoints[1];\n var targetTB = targetPoints[0];\n var targetLR = targetPoints[1];\n\n // Top & Bottom\n if (popupTB === targetTB || ![\'t\', \'b\'].includes(popupTB)) {\n alignStyle.top = y;\n } else if (popupTB === \'t\') {\n alignStyle.top = 0;\n } else {\n alignStyle.bottom = 0;\n }\n\n // Left & Right\n if (popupLR === targetLR || ![\'l\', \'r\'].includes(popupLR)) {\n alignStyle.left = x;\n } else if (popupLR === \'l\') {\n alignStyle.left = 0;\n } else {\n alignStyle.right = 0;\n }\n }\n return /*#__PURE__*/react.createElement("div", {\n ref: arrowRef,\n className: classnames_default()("".concat(prefixCls, "-arrow"), className),\n style: alignStyle\n }, content);\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/Mask.js\n\n\n\n\nfunction Mask(props) {\n var prefixCls = props.prefixCls,\n open = props.open,\n zIndex = props.zIndex,\n mask = props.mask,\n motion = props.motion;\n if (!mask) {\n return null;\n }\n return /*#__PURE__*/react.createElement(rc_motion_es, extends_extends({}, motion, {\n motionAppear: true,\n visible: open,\n removeOnLeave: true\n }), function (_ref) {\n var className = _ref.className;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n zIndex: zIndex\n },\n className: classnames_default()("".concat(prefixCls, "-mask"), className)\n });\n });\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/PopupContent.js\n\nvar PopupContent = /*#__PURE__*/react.memo(function (_ref) {\n var children = _ref.children;\n return children;\n}, function (_, next) {\n return next.cache;\n});\nif (false) {}\n/* harmony default export */ const Popup_PopupContent = (PopupContent);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/index.js\n\n\n\n\n\n\n\n\n\n\n\n\nvar Popup = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var popup = props.popup,\n className = props.className,\n prefixCls = props.prefixCls,\n style = props.style,\n target = props.target,\n _onVisibleChanged = props.onVisibleChanged,\n open = props.open,\n keepDom = props.keepDom,\n onClick = props.onClick,\n mask = props.mask,\n arrow = props.arrow,\n arrowPos = props.arrowPos,\n align = props.align,\n motion = props.motion,\n maskMotion = props.maskMotion,\n forceRender = props.forceRender,\n getPopupContainer = props.getPopupContainer,\n autoDestroy = props.autoDestroy,\n Portal = props.portal,\n zIndex = props.zIndex,\n onMouseEnter = props.onMouseEnter,\n onMouseLeave = props.onMouseLeave,\n ready = props.ready,\n offsetX = props.offsetX,\n offsetY = props.offsetY,\n onAlign = props.onAlign,\n onPrepare = props.onPrepare,\n stretch = props.stretch,\n targetWidth = props.targetWidth,\n targetHeight = props.targetHeight;\n var childNode = typeof popup === \'function\' ? popup() : popup;\n\n // We can not remove holder only when motion finished.\n var isNodeVisible = open || keepDom;\n\n // ======================= Container ========================\n var getPopupContainerNeedParams = (getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.length) > 0;\n var _React$useState = react.useState(!getPopupContainer || !getPopupContainerNeedParams),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n show = _React$useState2[0],\n setShow = _React$useState2[1];\n\n // Delay to show since `getPopupContainer` need target element\n hooks_useLayoutEffect(function () {\n if (!show && getPopupContainerNeedParams && target) {\n setShow(true);\n }\n }, [show, getPopupContainerNeedParams, target]);\n\n // ========================= Render =========================\n if (!show) {\n return null;\n }\n\n // >>>>> Offset\n var offsetStyle = ready || !open ? {\n left: offsetX,\n top: offsetY\n } : {\n left: \'-1000vw\',\n top: \'-1000vh\'\n };\n\n // >>>>> Misc\n var miscStyle = {};\n if (stretch) {\n if (stretch.includes(\'height\') && targetHeight) {\n miscStyle.height = targetHeight;\n } else if (stretch.includes(\'minHeight\') && targetHeight) {\n miscStyle.minHeight = targetHeight;\n }\n if (stretch.includes(\'width\') && targetWidth) {\n miscStyle.width = targetWidth;\n } else if (stretch.includes(\'minWidth\') && targetWidth) {\n miscStyle.minWidth = targetWidth;\n }\n }\n if (!open) {\n miscStyle.pointerEvents = \'none\';\n }\n return /*#__PURE__*/react.createElement(Portal, {\n open: forceRender || isNodeVisible,\n getContainer: getPopupContainer && function () {\n return getPopupContainer(target);\n },\n autoDestroy: autoDestroy\n }, /*#__PURE__*/react.createElement(Mask, {\n prefixCls: prefixCls,\n open: open,\n zIndex: zIndex,\n mask: mask,\n motion: maskMotion\n }), /*#__PURE__*/react.createElement(rc_resize_observer_es, {\n onResize: onAlign,\n disabled: !open\n }, function (resizeObserverRef) {\n return /*#__PURE__*/react.createElement(rc_motion_es, extends_extends({\n motionAppear: true,\n motionEnter: true,\n motionLeave: true,\n removeOnLeave: false,\n forceRender: forceRender,\n leavedClassName: "".concat(prefixCls, "-hidden")\n }, motion, {\n onAppearPrepare: onPrepare,\n onEnterPrepare: onPrepare,\n visible: open,\n onVisibleChanged: function onVisibleChanged(nextVisible) {\n var _motion$onVisibleChan;\n motion === null || motion === void 0 ? void 0 : (_motion$onVisibleChan = motion.onVisibleChanged) === null || _motion$onVisibleChan === void 0 ? void 0 : _motion$onVisibleChan.call(motion, nextVisible);\n _onVisibleChanged(nextVisible);\n }\n }), function (_ref, motionRef) {\n var motionClassName = _ref.className,\n motionStyle = _ref.style;\n var cls = classnames_default()(prefixCls, motionClassName, className);\n return /*#__PURE__*/react.createElement("div", {\n ref: composeRef(resizeObserverRef, ref, motionRef),\n className: cls,\n style: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({\n \'--arrow-x\': "".concat(arrowPos.x || 0, "px"),\n \'--arrow-y\': "".concat(arrowPos.y || 0, "px")\n }, offsetStyle), miscStyle), motionStyle), {}, {\n boxSizing: \'border-box\',\n zIndex: zIndex\n }, style),\n onMouseEnter: onMouseEnter,\n onMouseLeave: onMouseLeave,\n onClick: onClick\n }, arrow && /*#__PURE__*/react.createElement(Arrow, {\n prefixCls: prefixCls,\n arrow: arrow,\n arrowPos: arrowPos,\n align: align\n }), /*#__PURE__*/react.createElement(Popup_PopupContent, {\n cache: !open\n }, childNode));\n });\n }));\n});\nif (false) {}\n/* harmony default export */ const es_Popup = (Popup);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/TriggerWrapper.js\n\n\nvar TriggerWrapper = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var children = props.children,\n getTriggerDOMNode = props.getTriggerDOMNode;\n var canUseRef = supportRef(children);\n\n // When use `getTriggerDOMNode`, we should do additional work to get the real dom\n var setRef = react.useCallback(function (node) {\n fillRef(ref, getTriggerDOMNode ? getTriggerDOMNode(node) : node);\n }, [getTriggerDOMNode]);\n var mergedRef = useComposeRef(setRef, children.ref);\n return canUseRef ? /*#__PURE__*/react.cloneElement(children, {\n ref: mergedRef\n }) : children;\n});\nif (false) {}\n/* harmony default export */ const es_TriggerWrapper = (TriggerWrapper);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/index.js\n\n\n\nvar es_excluded = ["prefixCls", "children", "action", "showAction", "hideAction", "popupVisible", "defaultPopupVisible", "onPopupVisibleChange", "afterPopupVisibleChange", "mouseEnterDelay", "mouseLeaveDelay", "focusDelay", "blurDelay", "mask", "maskClosable", "getPopupContainer", "forceRender", "autoDestroy", "destroyPopupOnHide", "popup", "popupClassName", "popupStyle", "popupPlacement", "builtinPlacements", "popupAlign", "zIndex", "stretch", "getPopupClassNameFromAlign", "alignPoint", "onPopupClick", "onPopupAlign", "arrow", "popupMotion", "maskMotion", "popupTransitionName", "popupAnimation", "maskTransitionName", "maskAnimation", "className", "getTriggerDOMNode"];\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction generateTrigger() {\n var PortalComponent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : portal_es;\n var Trigger = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-trigger-popup\' : _props$prefixCls,\n children = props.children,\n _props$action = props.action,\n action = _props$action === void 0 ? \'hover\' : _props$action,\n showAction = props.showAction,\n hideAction = props.hideAction,\n popupVisible = props.popupVisible,\n defaultPopupVisible = props.defaultPopupVisible,\n onPopupVisibleChange = props.onPopupVisibleChange,\n afterPopupVisibleChange = props.afterPopupVisibleChange,\n mouseEnterDelay = props.mouseEnterDelay,\n _props$mouseLeaveDela = props.mouseLeaveDelay,\n mouseLeaveDelay = _props$mouseLeaveDela === void 0 ? 0.1 : _props$mouseLeaveDela,\n focusDelay = props.focusDelay,\n blurDelay = props.blurDelay,\n mask = props.mask,\n _props$maskClosable = props.maskClosable,\n maskClosable = _props$maskClosable === void 0 ? true : _props$maskClosable,\n getPopupContainer = props.getPopupContainer,\n forceRender = props.forceRender,\n autoDestroy = props.autoDestroy,\n destroyPopupOnHide = props.destroyPopupOnHide,\n popup = props.popup,\n popupClassName = props.popupClassName,\n popupStyle = props.popupStyle,\n popupPlacement = props.popupPlacement,\n _props$builtinPlaceme = props.builtinPlacements,\n builtinPlacements = _props$builtinPlaceme === void 0 ? {} : _props$builtinPlaceme,\n popupAlign = props.popupAlign,\n zIndex = props.zIndex,\n stretch = props.stretch,\n getPopupClassNameFromAlign = props.getPopupClassNameFromAlign,\n alignPoint = props.alignPoint,\n onPopupClick = props.onPopupClick,\n onPopupAlign = props.onPopupAlign,\n arrow = props.arrow,\n popupMotion = props.popupMotion,\n maskMotion = props.maskMotion,\n popupTransitionName = props.popupTransitionName,\n popupAnimation = props.popupAnimation,\n maskTransitionName = props.maskTransitionName,\n maskAnimation = props.maskAnimation,\n className = props.className,\n getTriggerDOMNode = props.getTriggerDOMNode,\n restProps = objectWithoutProperties_objectWithoutProperties(props, es_excluded);\n var mergedAutoDestroy = autoDestroy || destroyPopupOnHide || false;\n\n // =========================== Mobile ===========================\n var _React$useState = react.useState(false),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n mobile = _React$useState2[0],\n setMobile = _React$useState2[1];\n hooks_useLayoutEffect(function () {\n setMobile(es_isMobile());\n }, []);\n\n // ========================== Context ===========================\n var subPopupElements = react.useRef({});\n var parentContext = react.useContext(trigger_es_context);\n var context = react.useMemo(function () {\n return {\n registerSubPopup: function registerSubPopup(id, subPopupEle) {\n subPopupElements.current[id] = subPopupEle;\n parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, subPopupEle);\n }\n };\n }, [parentContext]);\n\n // =========================== Popup ============================\n var id = useId();\n var _React$useState3 = react.useState(null),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n popupEle = _React$useState4[0],\n setPopupEle = _React$useState4[1];\n var setPopupRef = useEvent(function (node) {\n if (isDOM(node) && popupEle !== node) {\n setPopupEle(node);\n }\n parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, node);\n });\n\n // =========================== Target ===========================\n // Use state to control here since `useRef` update not trigger render\n var _React$useState5 = react.useState(null),\n _React$useState6 = slicedToArray_slicedToArray(_React$useState5, 2),\n targetEle = _React$useState6[0],\n setTargetEle = _React$useState6[1];\n var setTargetRef = useEvent(function (node) {\n if (isDOM(node) && targetEle !== node) {\n setTargetEle(node);\n }\n });\n\n // ========================== Children ==========================\n var child = react.Children.only(children);\n var originChildProps = (child === null || child === void 0 ? void 0 : child.props) || {};\n var cloneProps = {};\n var inPopupOrChild = useEvent(function (ele) {\n var _childDOM$getRootNode, _popupEle$getRootNode;\n var childDOM = targetEle;\n return (childDOM === null || childDOM === void 0 ? void 0 : childDOM.contains(ele)) || (childDOM === null || childDOM === void 0 ? void 0 : (_childDOM$getRootNode = childDOM.getRootNode()) === null || _childDOM$getRootNode === void 0 ? void 0 : _childDOM$getRootNode.host) === ele || ele === childDOM || (popupEle === null || popupEle === void 0 ? void 0 : popupEle.contains(ele)) || (popupEle === null || popupEle === void 0 ? void 0 : (_popupEle$getRootNode = popupEle.getRootNode()) === null || _popupEle$getRootNode === void 0 ? void 0 : _popupEle$getRootNode.host) === ele || ele === popupEle || Object.values(subPopupElements.current).some(function (subPopupEle) {\n return (subPopupEle === null || subPopupEle === void 0 ? void 0 : subPopupEle.contains(ele)) || ele === subPopupEle;\n });\n });\n\n // =========================== Motion ===========================\n var mergePopupMotion = getMotion(prefixCls, popupMotion, popupAnimation, popupTransitionName);\n var mergeMaskMotion = getMotion(prefixCls, maskMotion, maskAnimation, maskTransitionName);\n\n // ============================ Open ============================\n var _React$useState7 = react.useState(defaultPopupVisible || false),\n _React$useState8 = slicedToArray_slicedToArray(_React$useState7, 2),\n internalOpen = _React$useState8[0],\n setInternalOpen = _React$useState8[1];\n\n // Render still use props as first priority\n var mergedOpen = popupVisible !== null && popupVisible !== void 0 ? popupVisible : internalOpen;\n\n // We use effect sync here in case `popupVisible` back to `undefined`\n var setMergedOpen = useEvent(function (nextOpen) {\n if (popupVisible === undefined) {\n setInternalOpen(nextOpen);\n }\n });\n hooks_useLayoutEffect(function () {\n setInternalOpen(popupVisible || false);\n }, [popupVisible]);\n var openRef = react.useRef(mergedOpen);\n openRef.current = mergedOpen;\n var internalTriggerOpen = useEvent(function (nextOpen) {\n if (mergedOpen !== nextOpen) {\n setMergedOpen(nextOpen);\n onPopupVisibleChange === null || onPopupVisibleChange === void 0 ? void 0 : onPopupVisibleChange(nextOpen);\n }\n });\n\n // Trigger for delay\n var delayRef = react.useRef();\n var clearDelay = function clearDelay() {\n clearTimeout(delayRef.current);\n };\n var triggerOpen = function triggerOpen(nextOpen) {\n var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n clearDelay();\n if (delay === 0) {\n internalTriggerOpen(nextOpen);\n } else {\n delayRef.current = setTimeout(function () {\n internalTriggerOpen(nextOpen);\n }, delay * 1000);\n }\n };\n react.useEffect(function () {\n return clearDelay;\n }, []);\n\n // ========================== Motion ============================\n var _React$useState9 = react.useState(false),\n _React$useState10 = slicedToArray_slicedToArray(_React$useState9, 2),\n inMotion = _React$useState10[0],\n setInMotion = _React$useState10[1];\n var mountRef = react.useRef(true);\n hooks_useLayoutEffect(function () {\n if (!mountRef.current || mergedOpen) {\n setInMotion(true);\n }\n mountRef.current = true;\n }, [mergedOpen]);\n var _React$useState11 = react.useState(null),\n _React$useState12 = slicedToArray_slicedToArray(_React$useState11, 2),\n motionPrepareResolve = _React$useState12[0],\n setMotionPrepareResolve = _React$useState12[1];\n\n // =========================== Align ============================\n var _React$useState13 = react.useState([0, 0]),\n _React$useState14 = slicedToArray_slicedToArray(_React$useState13, 2),\n mousePos = _React$useState14[0],\n setMousePos = _React$useState14[1];\n var setMousePosByEvent = function setMousePosByEvent(event) {\n setMousePos([event.clientX, event.clientY]);\n };\n var _useAlign = useAlign(mergedOpen, popupEle, alignPoint ? mousePos : targetEle, popupPlacement, builtinPlacements, popupAlign, onPopupAlign),\n _useAlign2 = slicedToArray_slicedToArray(_useAlign, 9),\n ready = _useAlign2[0],\n offsetX = _useAlign2[1],\n offsetY = _useAlign2[2],\n arrowX = _useAlign2[3],\n arrowY = _useAlign2[4],\n scaleX = _useAlign2[5],\n scaleY = _useAlign2[6],\n alignInfo = _useAlign2[7],\n onAlign = _useAlign2[8];\n var triggerAlign = useEvent(function () {\n if (!inMotion) {\n onAlign();\n }\n });\n useWatch(mergedOpen, targetEle, popupEle, triggerAlign);\n hooks_useLayoutEffect(function () {\n triggerAlign();\n }, [mousePos]);\n\n // When no builtinPlacements and popupAlign changed\n hooks_useLayoutEffect(function () {\n if (mergedOpen && !(builtinPlacements !== null && builtinPlacements !== void 0 && builtinPlacements[popupPlacement])) {\n triggerAlign();\n }\n }, [JSON.stringify(popupAlign)]);\n var alignedClassName = react.useMemo(function () {\n var baseClassName = getAlignPopupClassName(builtinPlacements, prefixCls, alignInfo, alignPoint);\n return classnames_default()(baseClassName, getPopupClassNameFromAlign === null || getPopupClassNameFromAlign === void 0 ? void 0 : getPopupClassNameFromAlign(alignInfo));\n }, [alignInfo, getPopupClassNameFromAlign, builtinPlacements, prefixCls, alignPoint]);\n react.useImperativeHandle(ref, function () {\n return {\n forceAlign: triggerAlign\n };\n });\n\n // ========================== Motion ============================\n var onVisibleChanged = function onVisibleChanged(visible) {\n setInMotion(false);\n onAlign();\n afterPopupVisibleChange === null || afterPopupVisibleChange === void 0 ? void 0 : afterPopupVisibleChange(visible);\n };\n\n // We will trigger align when motion is in prepare\n var onPrepare = function onPrepare() {\n return new Promise(function (resolve) {\n setMotionPrepareResolve(function () {\n return resolve;\n });\n });\n };\n hooks_useLayoutEffect(function () {\n if (motionPrepareResolve) {\n onAlign();\n motionPrepareResolve();\n setMotionPrepareResolve(null);\n }\n }, [motionPrepareResolve]);\n\n // ========================== Stretch ===========================\n var _React$useState15 = react.useState(0),\n _React$useState16 = slicedToArray_slicedToArray(_React$useState15, 2),\n targetWidth = _React$useState16[0],\n setTargetWidth = _React$useState16[1];\n var _React$useState17 = react.useState(0),\n _React$useState18 = slicedToArray_slicedToArray(_React$useState17, 2),\n targetHeight = _React$useState18[0],\n setTargetHeight = _React$useState18[1];\n var onTargetResize = function onTargetResize(_, ele) {\n triggerAlign();\n if (stretch) {\n var rect = ele.getBoundingClientRect();\n setTargetWidth(rect.width);\n setTargetHeight(rect.height);\n }\n };\n\n // =========================== Action ===========================\n var _useAction = useAction(mobile, action, showAction, hideAction),\n _useAction2 = slicedToArray_slicedToArray(_useAction, 2),\n showActions = _useAction2[0],\n hideActions = _useAction2[1];\n\n // Util wrapper for trigger action\n var wrapperAction = function wrapperAction(eventName, nextOpen, delay, preEvent) {\n cloneProps[eventName] = function (event) {\n var _originChildProps$eve;\n preEvent === null || preEvent === void 0 ? void 0 : preEvent(event);\n triggerOpen(nextOpen, delay);\n\n // Pass to origin\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n (_originChildProps$eve = originChildProps[eventName]) === null || _originChildProps$eve === void 0 ? void 0 : _originChildProps$eve.call.apply(_originChildProps$eve, [originChildProps, event].concat(args));\n };\n };\n\n // ======================= Action: Click ========================\n var clickToShow = showActions.has(\'click\');\n var clickToHide = hideActions.has(\'click\') || hideActions.has(\'contextMenu\');\n if (clickToShow || clickToHide) {\n cloneProps.onClick = function (event) {\n var _originChildProps$onC;\n if (openRef.current && clickToHide) {\n triggerOpen(false);\n } else if (!openRef.current && clickToShow) {\n setMousePosByEvent(event);\n triggerOpen(true);\n }\n\n // Pass to origin\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n (_originChildProps$onC = originChildProps.onClick) === null || _originChildProps$onC === void 0 ? void 0 : _originChildProps$onC.call.apply(_originChildProps$onC, [originChildProps, event].concat(args));\n };\n }\n\n // Click to hide is special action since click popup element should not hide\n react.useEffect(function () {\n if (clickToHide && popupEle && (!mask || maskClosable)) {\n var clickInside = false;\n\n // User may mouseDown inside and drag out of popup and mouse up\n // Record here to prevent close\n var onWindowMouseDown = function onWindowMouseDown(_ref) {\n var target = _ref.target;\n clickInside = inPopupOrChild(target);\n };\n var onWindowClick = function onWindowClick(_ref2) {\n var target = _ref2.target;\n if (openRef.current && !clickInside && !inPopupOrChild(target)) {\n triggerOpen(false);\n }\n };\n var win = getWin(popupEle);\n var targetRoot = targetEle === null || targetEle === void 0 ? void 0 : targetEle.getRootNode();\n win.addEventListener(\'mousedown\', onWindowMouseDown);\n win.addEventListener(\'click\', onWindowClick);\n\n // shadow root\n var inShadow = targetRoot && targetRoot !== targetEle.ownerDocument;\n if (inShadow) {\n targetRoot.addEventListener(\'mousedown\', onWindowMouseDown);\n targetRoot.addEventListener(\'click\', onWindowClick);\n }\n\n // Warning if target and popup not in same root\n if (false) { var popupRoot; }\n return function () {\n win.removeEventListener(\'mousedown\', onWindowMouseDown);\n win.removeEventListener(\'click\', onWindowClick);\n if (inShadow) {\n targetRoot.removeEventListener(\'mousedown\', onWindowMouseDown);\n targetRoot.removeEventListener(\'click\', onWindowClick);\n }\n };\n }\n }, [clickToHide, targetEle, popupEle, mask, maskClosable]);\n\n // ======================= Action: Hover ========================\n var hoverToShow = showActions.has(\'hover\');\n var hoverToHide = hideActions.has(\'hover\');\n var onPopupMouseEnter;\n var onPopupMouseLeave;\n if (hoverToShow) {\n wrapperAction(\'onMouseEnter\', true, mouseEnterDelay, function (event) {\n setMousePosByEvent(event);\n });\n onPopupMouseEnter = function onPopupMouseEnter() {\n triggerOpen(true, mouseEnterDelay);\n };\n\n // Align Point\n if (alignPoint) {\n cloneProps.onMouseMove = function (event) {\n var _originChildProps$onM;\n // setMousePosByEvent(event);\n (_originChildProps$onM = originChildProps.onMouseMove) === null || _originChildProps$onM === void 0 ? void 0 : _originChildProps$onM.call(originChildProps, event);\n };\n }\n }\n if (hoverToHide) {\n wrapperAction(\'onMouseLeave\', false, mouseLeaveDelay);\n onPopupMouseLeave = function onPopupMouseLeave() {\n triggerOpen(false, mouseLeaveDelay);\n };\n }\n\n // ======================= Action: Focus ========================\n if (showActions.has(\'focus\')) {\n wrapperAction(\'onFocus\', true, focusDelay);\n }\n if (hideActions.has(\'focus\')) {\n wrapperAction(\'onBlur\', false, blurDelay);\n }\n\n // ==================== Action: ContextMenu =====================\n if (showActions.has(\'contextMenu\')) {\n cloneProps.onContextMenu = function (event) {\n var _originChildProps$onC2;\n setMousePosByEvent(event);\n triggerOpen(true);\n event.preventDefault();\n\n // Pass to origin\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n (_originChildProps$onC2 = originChildProps.onContextMenu) === null || _originChildProps$onC2 === void 0 ? void 0 : _originChildProps$onC2.call.apply(_originChildProps$onC2, [originChildProps, event].concat(args));\n };\n }\n\n // ========================= ClassName ==========================\n if (className) {\n cloneProps.className = classnames_default()(originChildProps.className, className);\n }\n\n // =========================== Render ===========================\n var mergedChildrenProps = _objectSpread2(_objectSpread2({}, originChildProps), cloneProps);\n\n // Pass props into cloneProps for nest usage\n var passedProps = {};\n var passedEventList = [\'onContextMenu\', \'onClick\', \'onMouseDown\', \'onTouchStart\', \'onMouseEnter\', \'onMouseLeave\', \'onFocus\', \'onBlur\'];\n passedEventList.forEach(function (eventName) {\n if (restProps[eventName]) {\n passedProps[eventName] = function () {\n var _mergedChildrenProps$;\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n (_mergedChildrenProps$ = mergedChildrenProps[eventName]) === null || _mergedChildrenProps$ === void 0 ? void 0 : _mergedChildrenProps$.call.apply(_mergedChildrenProps$, [mergedChildrenProps].concat(args));\n restProps[eventName].apply(restProps, args);\n };\n }\n });\n\n // Child Node\n var triggerNode = /*#__PURE__*/react.cloneElement(child, _objectSpread2(_objectSpread2({}, mergedChildrenProps), passedProps));\n var arrowPos = {\n x: arrowX,\n y: arrowY\n };\n var innerArrow = arrow ? _objectSpread2({}, arrow !== true ? arrow : {}) : null;\n\n // Render\n return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(rc_resize_observer_es, {\n disabled: !mergedOpen,\n ref: setTargetRef,\n onResize: onTargetResize\n }, /*#__PURE__*/react.createElement(es_TriggerWrapper, {\n getTriggerDOMNode: getTriggerDOMNode\n }, triggerNode)), /*#__PURE__*/react.createElement(trigger_es_context.Provider, {\n value: context\n }, /*#__PURE__*/react.createElement(es_Popup, {\n portal: PortalComponent,\n ref: setPopupRef,\n prefixCls: prefixCls,\n popup: popup,\n className: classnames_default()(popupClassName, alignedClassName),\n style: popupStyle,\n target: targetEle,\n onMouseEnter: onPopupMouseEnter,\n onMouseLeave: onPopupMouseLeave,\n zIndex: zIndex\n // Open\n ,\n open: mergedOpen,\n keepDom: inMotion\n // Click\n ,\n onClick: onPopupClick\n // Mask\n ,\n mask: mask\n // Motion\n ,\n motion: mergePopupMotion,\n maskMotion: mergeMaskMotion,\n onVisibleChanged: onVisibleChanged,\n onPrepare: onPrepare\n // Portal\n ,\n forceRender: forceRender,\n autoDestroy: mergedAutoDestroy,\n getPopupContainer: getPopupContainer\n // Arrow\n ,\n align: alignInfo,\n arrow: innerArrow,\n arrowPos: arrowPos\n // Align\n ,\n ready: ready,\n offsetX: offsetX,\n offsetY: offsetY,\n onAlign: triggerAlign\n // Stretch\n ,\n stretch: stretch,\n targetWidth: targetWidth / scaleX,\n targetHeight: targetHeight / scaleY\n })));\n });\n if (false) {}\n return Trigger;\n}\n/* harmony default export */ const trigger_es = (generateTrigger(portal_es));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/placements.js\nvar autoAdjustOverflowTopBottom = {\n shiftX: 64,\n adjustY: 1\n};\nvar autoAdjustOverflowLeftRight = {\n adjustX: 1,\n shiftY: true\n};\nvar targetOffset = [0, 0];\nvar placements = {\n left: {\n points: [\'cr\', \'cl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n },\n right: {\n points: [\'cl\', \'cr\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n top: {\n points: [\'bc\', \'tc\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n bottom: {\n points: [\'tc\', \'bc\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n topLeft: {\n points: [\'bl\', \'tl\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n leftTop: {\n points: [\'tr\', \'tl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n },\n topRight: {\n points: [\'br\', \'tr\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n rightTop: {\n points: [\'tl\', \'tr\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n bottomRight: {\n points: [\'tr\', \'br\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n rightBottom: {\n points: [\'bl\', \'br\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n bottomLeft: {\n points: [\'tl\', \'bl\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n leftBottom: {\n points: [\'br\', \'bl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n }\n};\n/* harmony default export */ const es_placements = ((/* unused pure expression or super */ null && (placements)));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/Popup.js\n\n\nfunction Popup_Popup(props) {\n var children = props.children,\n prefixCls = props.prefixCls,\n id = props.id,\n overlayInnerStyle = props.overlayInnerStyle,\n className = props.className,\n style = props.style;\n return /*#__PURE__*/react.createElement("div", {\n className: classnames_default()("".concat(prefixCls, "-content"), className),\n style: style\n }, /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-inner"),\n id: id,\n role: "tooltip",\n style: overlayInnerStyle\n }, typeof children === \'function\' ? children() : children));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/Tooltip.js\n\n\n\nvar Tooltip_excluded = ["overlayClassName", "trigger", "mouseEnterDelay", "mouseLeaveDelay", "overlayStyle", "prefixCls", "children", "onVisibleChange", "afterVisibleChange", "transitionName", "animation", "motion", "placement", "align", "destroyTooltipOnHide", "defaultVisible", "getTooltipContainer", "overlayInnerStyle", "arrowContent", "overlay", "id", "showArrow"];\n\n\n\n\n\nvar Tooltip = function Tooltip(props, ref) {\n var overlayClassName = props.overlayClassName,\n _props$trigger = props.trigger,\n trigger = _props$trigger === void 0 ? [\'hover\'] : _props$trigger,\n _props$mouseEnterDela = props.mouseEnterDelay,\n mouseEnterDelay = _props$mouseEnterDela === void 0 ? 0 : _props$mouseEnterDela,\n _props$mouseLeaveDela = props.mouseLeaveDelay,\n mouseLeaveDelay = _props$mouseLeaveDela === void 0 ? 0.1 : _props$mouseLeaveDela,\n overlayStyle = props.overlayStyle,\n _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-tooltip\' : _props$prefixCls,\n children = props.children,\n onVisibleChange = props.onVisibleChange,\n afterVisibleChange = props.afterVisibleChange,\n transitionName = props.transitionName,\n animation = props.animation,\n motion = props.motion,\n _props$placement = props.placement,\n placement = _props$placement === void 0 ? \'right\' : _props$placement,\n _props$align = props.align,\n align = _props$align === void 0 ? {} : _props$align,\n _props$destroyTooltip = props.destroyTooltipOnHide,\n destroyTooltipOnHide = _props$destroyTooltip === void 0 ? false : _props$destroyTooltip,\n defaultVisible = props.defaultVisible,\n getTooltipContainer = props.getTooltipContainer,\n overlayInnerStyle = props.overlayInnerStyle,\n arrowContent = props.arrowContent,\n overlay = props.overlay,\n id = props.id,\n _props$showArrow = props.showArrow,\n showArrow = _props$showArrow === void 0 ? true : _props$showArrow,\n restProps = objectWithoutProperties_objectWithoutProperties(props, Tooltip_excluded);\n var triggerRef = (0,react.useRef)(null);\n (0,react.useImperativeHandle)(ref, function () {\n return triggerRef.current;\n });\n var extraProps = _objectSpread2({}, restProps);\n if (\'visible\' in props) {\n extraProps.popupVisible = props.visible;\n }\n var getPopupElement = function getPopupElement() {\n return /*#__PURE__*/react.createElement(Popup_Popup, {\n key: "content",\n prefixCls: prefixCls,\n id: id,\n overlayInnerStyle: overlayInnerStyle\n }, overlay);\n };\n return /*#__PURE__*/react.createElement(trigger_es, extends_extends({\n popupClassName: overlayClassName,\n prefixCls: prefixCls,\n popup: getPopupElement,\n action: trigger,\n builtinPlacements: placements,\n popupPlacement: placement,\n ref: triggerRef,\n popupAlign: align,\n getPopupContainer: getTooltipContainer,\n onPopupVisibleChange: onVisibleChange,\n afterPopupVisibleChange: afterVisibleChange,\n popupTransitionName: transitionName,\n popupAnimation: animation,\n popupMotion: motion,\n defaultPopupVisible: defaultVisible,\n autoDestroy: destroyTooltipOnHide,\n mouseLeaveDelay: mouseLeaveDelay,\n popupStyle: overlayStyle,\n mouseEnterDelay: mouseEnterDelay,\n arrow: showArrow\n }, extraProps), children);\n};\n/* harmony default export */ const es_Tooltip = (/*#__PURE__*/(0,react.forwardRef)(Tooltip));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/index.js\n\n\n\n/* harmony default export */ const rc_tooltip_es = (es_Tooltip);\n;// CONCATENATED MODULE: ./src/ui/TooltipSlider.tsx\n/**\n * rc-tooltip tooltip slider\n */\nvar TooltipSlider_assign = (undefined && undefined.__assign) || function () {\n TooltipSlider_assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return TooltipSlider_assign.apply(this, arguments);\n};\nvar TooltipSlider_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\nvar HandleTooltip = function (props) {\n var value = props.value, children = props.children, visible = props.visible, _a = props.tipFormatter, tipFormatter = _a === void 0 ? function (val) { return "".concat(val, " %"); } : _a, restProps = TooltipSlider_rest(props, ["value", "children", "visible", "tipFormatter"]);\n var tooltipRef = react.useRef();\n var rafRef = react.useRef(null);\n function cancelKeepAlign() {\n raf/* default.cancel */.Z.cancel(rafRef.current);\n }\n function keepAlign() {\n rafRef.current = (0,raf/* default */.Z)(function () {\n // tooltipRef.current?.forcePopupAlign();\n });\n }\n react.useEffect(function () {\n if (visible) {\n keepAlign();\n }\n else {\n cancelKeepAlign();\n }\n return cancelKeepAlign;\n }, [value, visible]);\n return (react.createElement(rc_tooltip_es, TooltipSlider_assign({ placement: "top", overlay: tipFormatter(value), overlayInnerStyle: { minHeight: "auto" }, ref: tooltipRef, visible: visible }, restProps), children));\n};\nvar handleRender = function (node, props) {\n return (React.createElement(HandleTooltip, { value: props.value, visible: props.dragging }, node));\n};\nvar TooltipSlider = function (_a) {\n var tipFormatter = _a.tipFormatter, tipProps = _a.tipProps, props = TooltipSlider_rest(_a, ["tipFormatter", "tipProps"]);\n var tipHandleRender = function (node, handleProps) {\n return (react.createElement(HandleTooltip, TooltipSlider_assign({ value: handleProps.value, visible: handleProps.dragging, tipFormatter: tipFormatter }, tipProps), node));\n };\n return react.createElement(es, TooltipSlider_assign({}, props, { handleRender: tipHandleRender }));\n};\n/* harmony default export */ const ui_TooltipSlider = (TooltipSlider);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./node_modules/rc-slider/assets/index.css\nvar assets = __webpack_require__(687);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/assets/index.css\n\n \n \n \n \n \n \n \n \n \n\nvar assets_options = {};\n\nassets_options.styleTagTransform = (styleTagTransform_default());\nassets_options.setAttributes = (setAttributesWithoutAttributes_default());\n\n assets_options.insert = insertBySelector_default().bind(null, "head");\n \nassets_options.domAPI = (styleDomAPI_default());\nassets_options.insertStyleElement = (insertStyleElement_default());\n\nvar assets_update = injectStylesIntoStyleTag_default()(assets/* default */.Z, assets_options);\n\n\n\n\n /* harmony default export */ const rc_slider_assets = (assets/* default */.Z && assets/* default.locals */.Z.locals ? assets/* default.locals */.Z.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/ui/Controls.jsx\n/**\n * Relabi controls\n * @module src/ui/Controls.jsx;\n */\n\n\n\n\n\n\nvar WAVE_SHAPE_NAMES = ["sine", "triangle", "saw", "square"];\nfunction Controls(_ref) {\n var relabi = _ref.relabi;\n /**\n * Handle updating a slider\n */\n var onChange = (0,react.useCallback)(function (type, index) {\n return function (value) {\n if (type === "bound") {\n relabi.bounds[index].level = value;\n }\n if (type === "frequency") {\n relabi.waves[index].frequency = Math.exp(value);\n }\n if (type === "shape") {\n relabi.waves[index].shape = WAVE_SHAPE_NAMES[value];\n }\n };\n }, [relabi]);\n return /*#__PURE__*/react.createElement(ControlRow, null, /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Bounds"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.bounds.map(function (bound, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "bound_".concat(index),\n type: "bound",\n index: index,\n onChange: onChange,\n min: -1,\n max: 1,\n step: 0.01,\n defaultValue: bound.level,\n color: bound.color,\n reverse: true\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Wave speeds"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.waves.map(function (wave, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "frequency_".concat(index),\n type: "frequency",\n index: index,\n onChange: onChange,\n min: -2,\n max: 3,\n step: 0.001,\n defaultValue: Math.log(wave.frequency),\n color: "#8a8"\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Wave shapes"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.waves.map(function (wave, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "shape_".concat(index),\n type: "shape",\n index: index,\n onChange: onChange,\n min: 0,\n max: 3,\n step: 1,\n defaultValue: WAVE_SHAPE_NAMES.indexOf(wave.shape),\n color: "#998",\n tipFormatter: function tipFormatter(value) {\n return WAVE_SHAPE_NAMES[value];\n }\n });\n }))));\n}\n\n/**\n * UI Elements\n */\nvar ControlRow = function ControlRow(_ref2) {\n var children = _ref2.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n display: "flex",\n flexDirection: "row",\n marginTop: "1rem"\n }\n }, children);\n};\nvar ControlBox = function ControlBox(_ref3) {\n var children = _ref3.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n marginLeft: "1rem"\n }\n }, children);\n};\nvar SliderRow = function SliderRow(_ref4) {\n var children = _ref4.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n display: "flex",\n flexDireciton: "row",\n height: "10rem",\n marginTop: "0.5rem"\n }\n }, children);\n};\nvar Label = function Label(_ref5) {\n var children = _ref5.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n fontSize: "0.75rem"\n }\n }, children);\n};\nvar ControlSlider = function ControlSlider(_ref6) {\n var type = _ref6.type,\n index = _ref6.index,\n min = _ref6.min,\n max = _ref6.max,\n step = _ref6.step,\n reverse = _ref6.reverse,\n defaultValue = _ref6.defaultValue,\n color = _ref6.color,\n onChange = _ref6.onChange,\n tipFormatter = _ref6.tipFormatter;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n marginRight: "0.5rem"\n }\n }, /*#__PURE__*/react.createElement(ui_TooltipSlider, {\n vertical: true,\n min: min,\n max: max,\n step: step,\n reverse: reverse,\n defaultValue: defaultValue,\n onChange: onChange(type, index),\n handleStyle: {\n backgroundColor: color,\n borderColor: color,\n opacity: 1\n },\n trackStyle: {\n backgroundColor: "#888",\n width: "2px"\n },\n railStyle: {\n backgroundColor: "#888",\n width: "2px"\n },\n tipFormatter: tipFormatter || function (value) {\n return value;\n }\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\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 shape: "sine",\n frequency: 0.75\n }, {\n shape: "sine",\n frequency: 1.0\n }, {\n shape: "sine",\n frequency: 1.617\n }, {\n shape: "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 }), /*#__PURE__*/react.createElement(Controls, {\n relabi: relabi\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.style.fontFamily = "Helvetica, Arial";\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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LGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBO0FBQ0EscURBQXFEO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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LFlBQVksa0JBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxjQUFjO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCLGdCQUFnQixjQUFjO0FBQzlCO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixZQUFZO0FBQzVCO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsZ0JBQWdCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUM7O0FDemRrQztBQUNVO0FBQ3JDLDJCQUEyQixXQUFXO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0M7O0FDeklzQztBQUN0QztBQUNBO0FBQ0E7QUFDTyxTQUFTLGtCQUFRO0FBQ3hCLFFBQVEsaUJBQU87QUFDZixnQ0FBZ0Msa0JBQVE7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxrQkFBUTtBQUN4QixRQUFRLGlCQUFPO0FBQ2YsZ0NBQWdDLGtCQUFRO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDTyxNQUFNLGNBQUk7QUFDakI7QUFDQTtBQUNBLHFDOztBQy9Ca0M7QUFDSztBQUNSO0FBQzJCO0FBQ0Y7QUFDZjtBQUN1QjtBQUN6QjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ08sTUFBTSwrQkFBZSxTQUFTLElBQUk7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLGNBQUk7QUFDMUIsd0JBQXdCLDZCQUFvQixDQUFDLCtCQUFlO0FBQzVEO0FBQ0E7QUFDQSwyQkFBMkIsYUFBYSx3Q0FBd0MsK0JBQWU7QUFDL0Y7QUFDQTtBQUNBLGlCQUFpQixrQkFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsY0FBSTtBQUN6QixvQkFBb0IsY0FBSTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGlCQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwrQkFBZTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEIsZ0NBQWdDLCtCQUFlO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixZQUFZLCtCQUFlO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4QkFBOEIsK0JBQWU7QUFDN0MsZ0JBQWdCLCtCQUFlO0FBQy9CO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLGlCQUFPO0FBQzFDO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQVU7QUFDbEM7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLGNBQWM7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGtCQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsdUJBQXVCO0FBQ3pEO0FBQ0EsZ0NBQWdDLHlCQUF5QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGtCQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDJCQUEyQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBLDBCQUEwQixpQkFBVTtBQUNwQyw4QkFBOEIsaUNBQWlDO0FBQy9EO0FBQ0E7QUFDQSxtQkFBbUIsK0JBQWU7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLDJCQUEyQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsK0JBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCLCtCQUErQiwrQkFBZTtBQUM5QztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsK0JBQWU7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsK0JBQWUsbUJBQW1CLCtCQUFlLHlCQUF5QiwrQkFBZSxXQUFXLCtCQUFlO0FBQy9JO0FBQ0E7QUFDQSx1REFBdUQsSUFBSTtBQUMzRDtBQUNBO0FBQ0Esc0NBQXNDLGlCQUFVO0FBQ2hEO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pELDhEQUE4RDtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBUztBQUN4QjtBQUNBO0FBQ0EsbUJBQW1CLCtCQUFlO0FBQ2xDLHNCQUFzQiwrQkFBZTtBQUNyQztBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQSwrQkFBZTtBQUNmLDJDOztBQzFXa0M7QUFDa0M7QUFDdkI7QUFDcUI7QUFDZDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsU0FBUztBQUM5QztBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ08sTUFBTSw2QkFBYyxTQUFTLE9BQU87QUFDM0M7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHFCQUFxQjtBQUMxQywrQkFBK0IseUJBQXlCO0FBQ3hEO0FBQ0EsNEJBQTRCLHFCQUFxQjtBQUNqRDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIscUJBQXFCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxpQkFBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsK0JBQWU7QUFDdEMsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQzs7QUN0RnFDO0FBQytCO0FBQ3hCO0FBQ1U7QUFDSTtBQUN1QjtBQUNqRjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsWUFBWTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLGlCQUFVO0FBQzFCLDBDQUEwQyxlQUFlO0FBQ3pELFFBQVEsaUJBQVUsS0FBSyxPQUFPO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyxpQkFBVTtBQUMxQixRQUFRLGNBQWM7QUFDdEIsNEJBQTRCLE9BQU87QUFDbkM7QUFDQSxhQUFhLHFCQUFxQjtBQUNsQyw0QkFBNEIsNkJBQWM7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLHNCQUFTLEtBQUssMkNBQThCO0FBQ2hEO0FBQ0EsUUFBUSxPQUFPO0FBQ2Y7QUFDQTtBQUNBLHNDQUFzQyxPQUFPLEVBQUUsT0FBTyxFQUFFO0FBQ3hEO0FBQ0EscUJBQXFCLFlBQVksc0JBQXNCO0FBQ3ZEO0FBQ0Esa0M7O0FDcEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLG9CQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLG9CQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQyxzQ0FBc0M7QUFDdEMsdUNBQXVDO0FBQ3ZDO0FBQ08sU0FBUyxvQ0FBd0I7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNPLFNBQVMsZ0JBQUk7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDTyxTQUFTLGdCQUFJO0FBQ3BCO0FBQ0E7QUFDQSx1Qzs7QUNuRStCO0FBQzRDO0FBQzNFO0FBQ0E7QUFDQTtBQUNPLDRCQUE0QixJQUFJO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxpQkFBTztBQUNuQjtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFRLGVBQWUsaUJBQU87QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQVE7QUFDekI7QUFDQTtBQUNBLG9CQUFvQixtQkFBUztBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsa0JBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQzFQdUM7QUFDRjtBQUNNO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ08sd0JBQXdCLGFBQWE7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDLDJDQUEyQztBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixXQUFXO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxnQkFBSTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQSxnQzs7QUNsSnVDO0FBQ3dCO0FBQ1o7QUFDaEI7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLHdCQUFjLFNBQVMsU0FBUztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsS0FBSztBQUNwQjtBQUNBO0FBQ0EsUUFBUSxLQUFLO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQix3QkFBYztBQUM3QztBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQSxpQ0FBaUMsRUFBRTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQix3QkFBYztBQUM3QztBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBLG1CQUFtQix3QkFBYyxnQ0FBZ0Msb0NBQXdCO0FBQ3pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0EsZUFBZSxnQkFBSTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsd0JBQWM7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGdCQUFJO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0JBQUk7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUCxlQUFlLHdCQUFjO0FBQzdCO0FBQ0EscUM7O0FDaE91QztBQUNKO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxnQ0FBa0IsU0FBUyxTQUFTO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsZUFBZSxnQ0FBa0I7QUFDakM7QUFDQSx5Qzs7QUMvQnVDO0FBQ1I7QUFDb0I7QUFDVjtBQUNrQjtBQUNzQjtBQUNjO0FBQy9GO0FBQ0E7QUFDQTtBQUNPLE1BQU0sK0JBQWUsU0FBUyxJQUFJO0FBQ3pDO0FBQ0E7QUFDQSx3QkFBd0IsNkJBQW9CLENBQUMsK0JBQWU7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLGlCQUFVO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHdCQUFjO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0NBQWtCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQU87QUFDdkI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsdUJBQXVCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixtQkFBUyxZQUFZLG1CQUFTLGtCQUFrQixtQkFBUztBQUM3RTtBQUNBO0FBQ0EsMkNBQTJDLCtCQUFlO0FBQzFEO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixpQkFBTyxZQUFZLGtCQUFRLFlBQVksa0JBQVEsWUFBWSxtQkFBUztBQUM3RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELG1CQUFTO0FBQ3pELHVDQUF1QyxtQkFBUywyQkFBMkIsbUJBQVM7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCwrQkFBZTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsMkM7O0FDektzQztBQUNBO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSwyQkFBYSxTQUFTLFFBQVE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGlCQUFXO0FBQ25CLGlDQUFpQztBQUNqQztBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsUUFBUTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOztBQzdFeUQ7QUFDQTtBQUNEO0FBQ1o7QUFDRTtBQUNNO0FBQ2xCO0FBQ2tCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxXQUFLLFNBQVMsK0JBQWU7QUFDMUM7QUFDQSxjQUFjLDZCQUFvQixDQUFDLFdBQUs7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLFdBQUs7QUFDbEQsUUFBUSxZQUFNLENBQUMsbUJBQVM7QUFDeEIsYUFBYSxZQUFZLDRDQUE0QyxXQUFLO0FBQzFFLGdCQUFnQixZQUFZO0FBQzVCO0FBQ0E7QUFDQSwwQkFBMEIsbUJBQVM7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFFBQVE7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QiwyQ0FBMkI7QUFDeEQ7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQVMsbUJBQW1CLG1CQUFTO0FBQ2pELFlBQVksaUJBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsb0JBQVE7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLG9CQUFRO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTSw2RkFBNkYsc0JBQXNCLElBQUkscUJBQXFCO0FBQzFKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTSxzR0FBc0csc0JBQXNCLElBQUksd0JBQXdCO0FBQ3RLO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsRUFBRTtBQUN6QjtBQUNBO0FBQ0EsUUFBUSxZQUFNLDJHQUEyRyxzQkFBc0IsSUFBSSx3QkFBd0I7QUFDM0s7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBLFFBQVEsWUFBTSw4RkFBOEYsc0JBQXNCLElBQUksMEJBQTBCO0FBQ2hLO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsbUJBQW1CO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLHVFQUF1RSxxQkFBcUI7QUFDMUc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLHFFQUFxRSxxQkFBcUI7QUFDeEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixFQUFFO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixhQUFhO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDOztBQzdic0U7QUFDeEI7QUFDZDtBQUNvQjtBQUNQO0FBQzdDO0FBQ0E7QUFDQTtBQUNPLE1BQU0sMkJBQWEsU0FBUywrQkFBZTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQVM7QUFDckIsZ0JBQWdCLFlBQVksc0NBQXNDLFdBQUs7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG1CQUFTLDJCQUEyQiwyQkFBYSxJQUFJLDZCQUFXO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRCxjQUFjO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRCxrQkFBa0I7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBELHVCQUF1QjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxxQkFBTztBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsVUFBSTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsd0JBQVU7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDJCQUFhO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQVM7QUFDckIsc0NBQXNDLDJCQUFhO0FBQ25EO0FBQ0E7QUFDQSxxQkFBcUIsNkJBQVc7QUFDaEM7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBUztBQUNyQix1Q0FBdUMsMkJBQWE7QUFDcEQ7QUFDQTtBQUNBLHFCQUFxQiw2QkFBVztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUywyQkFBYTtBQUM3QjtBQUNBO0FBQ0EsNEJBQTRCLDJCQUFhO0FBQ3pDO0FBQ0E7QUFDQSxpQkFBaUIsNkJBQVc7QUFDNUIsWUFBWSxxQkFBTztBQUNuQjtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVMscUJBQU87QUFDdkIsSUFBSSxZQUFNLENBQUMsbUJBQVM7QUFDcEIsSUFBSSxZQUFNLENBQUMsbUJBQVM7QUFDcEIsMkJBQTJCLDJCQUFhLElBQUksNkJBQVc7QUFDdkQsUUFBUSxZQUFNO0FBQ2Q7QUFDQSxJQUFJLFlBQU07QUFDVjtBQUNBLCtCQUErQiwyQkFBYSx1QkFBdUIsV0FBSztBQUN4RSxZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QiwyQkFBYTtBQUMzQyxZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFZO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBUyx3QkFBVTtBQUMxQjtBQUNBLFFBQVEsbUJBQVM7QUFDakIsa0NBQWtDLDJCQUFhO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSw2QkFBVztBQUN4QixZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBWTtBQUNwQjtBQUNBO0FBQ0EsYUFBYSw2QkFBVztBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUNyVXlDO0FBQ2U7QUFDWDtBQUNHO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDTyxNQUFNLFNBQUksU0FBUywyQkFBYTtBQUN2QztBQUNBLGNBQWMsNkJBQW9CLENBQUMsU0FBSTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLFNBQUk7QUFDakQsd0JBQXdCLFdBQUs7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ3pENEM7QUFDbUI7QUFDakI7QUFDRjtBQUM1QztBQUNBO0FBQ0E7QUFDTyw0QkFBNEIsMkJBQWE7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLGNBQUk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFNBQUk7QUFDOUI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQixjQUFJO0FBQ3pCLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBSTtBQUNqQztBQUNBO0FBQ0EsMkJBQTJCLGNBQUk7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUN0THdEO0FBQ1Y7QUFDZTtBQUNMO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLHFDQUFrQixTQUFTLGFBQWE7QUFDckQ7QUFDQSxjQUFjLDZCQUFvQixDQUFDLHFDQUFrQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLHFDQUFrQjtBQUMvRCxRQUFRLHFCQUFPO0FBQ2YsMEJBQTBCLFdBQUs7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLDZCQUE2Qix5QkFBeUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEM7O0FDNUQ4QztBQUNnQjtBQUNOO0FBQ007QUFDRDtBQUNIO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGFBQU0sU0FBUywyQkFBYTtBQUN6QztBQUNBLGNBQWMsNkJBQW9CLENBQUMsYUFBTTtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLGFBQU07QUFDbkQsaURBQWlELHFDQUFrQjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxRQUFRLG9CQUFhO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTLG9CQUFhO0FBQzdCLCtCQUErQixXQUFLLElBQUksWUFBWTtBQUNwRCxnQ0FBZ0MsYUFBTTtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLGFBQU07QUFDekM7QUFDQTtBQUNBO0FBQ0EsSUFBSSxxQkFBTztBQUNYO0FBQ0Esa0M7O0FDdEx5QztBQUNlO0FBQ1o7QUFDQTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sd0JBQXdCLFdBQUs7QUFDcEM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixRQUFRO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUJBQWlCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZUFBZTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsaUJBQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNU82QztBQUNXO0FBQ2hCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHlCQUF5QixhQUFNO0FBQ3RDO0FBQ0EsY0FBYyw2QkFBb0I7QUFDbEM7QUFDQSx3QkFBd0IsNkJBQW9CO0FBQzVDLHVDQUF1QyxTQUFTO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsNkJBQTZCLHlCQUFrQjtBQUMvQztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUMvRDZEO0FBQ0w7QUFDWDtBQUNTO0FBQ1Y7QUFDRTtBQUNKO0FBQ1I7QUFDbEM7QUFDQTtBQUNBO0FBQ08seUJBQXlCLCtCQUFlO0FBQy9DO0FBQ0EsY0FBYyw2QkFBb0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsMkJBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLFFBQVE7QUFDdkMsd0JBQXdCLDZCQUFvQjtBQUM1Qyw2QkFBNkIsVUFBVTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLEVBQUUsMkNBQTJCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsbUJBQVM7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsRUFBRTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQzNSNkQ7QUFDTDtBQUNkO0FBQ1M7QUFDRztBQUNaO0FBQ1c7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDTyxNQUFNLFdBQUssU0FBUywrQkFBZTtBQUMxQztBQUNBLGNBQWMsNkJBQW9CLENBQUMsV0FBSztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixjQUFJO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLDJCQUFhO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNkJBQW9CLENBQUMsV0FBSztBQUNsRDtBQUNBLCtCQUErQixVQUFVO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsMkNBQTJCO0FBQ3hELHNCQUFzQixjQUFJO0FBQzFCO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxvQkFBb0I7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0Msb0JBQW9CO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixXQUFXO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDMWhCOEI7QUFDOUI7QUFDa0M7QUFDSTtBQUNOO0FBQ2hDO0FBQytCO0FBQ0c7QUFDTztBQUNUO0FBQ1U7QUFDQztBQUNIO0FBQ1A7QUFDTDtBQUNBO0FBQ0M7QUFDUTtBQUNoQjtBQUNVO0FBQ1M7QUFDSDtBQUNMO0FBQ0M7QUFDNkQ7QUFDM0I7QUFDbkU7QUFDcUM7QUFDckI7QUFDaEI7QUFDc0M7QUFDckI7QUFDakIsaUM7O0FDaEMrQztBQUNrQjtBQUNEO0FBQ1g7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sYUFBTSxTQUFTLDJCQUFhO0FBQ3pDO0FBQ0EsY0FBYyw2QkFBb0IsQ0FBQyxhQUFNO0FBQ3pDO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLGFBQU07QUFDbkQsdUNBQXVDLFNBQUk7QUFDM0M7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUNqRXdEO0FBQ0E7QUFDZ0I7QUFDMUM7QUFDaUM7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sMEJBQTBCLDJCQUFhO0FBQzlDO0FBQ0EsY0FBYyw2QkFBb0I7QUFDbEM7QUFDQSx5QkFBeUIsYUFBTSxHQUFHLHVCQUF1QjtBQUN6RCwwQkFBMEIsU0FBSSxHQUFHLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsNkJBQW9CO0FBQzVDLFFBQVEsMkJBQWE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDJCQUFhO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLDRDQUE0QyxTQUFTO0FBQ3JELENBQUM7QUFDRCxjQUFjO0FBQ2Q7QUFDQSxDQUFDO0FBQ0QsdUM7O0FDeEdzQztBQUNQO0FBQy9CO0FBQ0E7QUFDQTtBQUNPLDRCQUE0QixJQUFJO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRLEdBQUcsWUFBWTtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOztBQ3hDeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsY0FBSTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDOztBQ3BEMkM7QUFDTztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNPLG1DQUFtQyxjQUFjO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGdCQUFVO0FBQ3RDLDZCQUE2QixnQkFBVTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixFQUFFLDBCQUEwQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUZBQW1GLGdCQUFVO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0ZBQWtGLGdCQUFVO0FBQzVGO0FBQ0EsK0VBQStFLGdCQUFVO0FBQ3pGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0Q7O0FDOUZpRDtBQUNhO0FBQ21CO0FBQzFDO0FBQ3NCO0FBQ2xCO0FBQ2dCO0FBQ0g7QUFDZDtBQUNhO0FBQ0s7QUFDaEI7QUFDVztBQUN2QjtBQUNrQjtBQUNZO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDTyx3QkFBd0IsK0JBQWU7QUFDOUM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixhQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixRQUFRO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxnQkFBZ0I7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw2QkFBb0I7QUFDNUM7QUFDQTtBQUNBLDBCQUEwQixXQUFLO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQSw2QkFBNkIsMkNBQTJCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsZ0JBQVU7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsMEJBQTBCLGNBQWM7QUFDeEM7QUFDQSxzQkFBc0IsZ0NBQWtCO0FBQ3hDLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsMEJBQTBCLG9CQUFvQjtBQUM5QztBQUNBLDBCQUEwQixTQUFTO0FBQ25DLDBCQUEwQixTQUFTO0FBQ25DLHNCQUFzQixnQ0FBa0I7QUFDeEMsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsY0FBYztBQUN4QztBQUNBO0FBQ0Esc0JBQXNCLGdDQUFrQjtBQUN4QyxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLGdCQUFVO0FBQ25DO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFPO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLFNBQVM7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixnQkFBVTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxTQUFJO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCxRQUFRO0FBQzdEO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxrQkFBUTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxrQkFBUTtBQUNqRTtBQUNBO0FB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LHNDQUFzQyx1QkFBdUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCOztBQ3hPc0M7QUFDdEM7QUFDQTtBQUNBO0FB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBELE1BQU07QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUMzSm1DO0FBQ2M7QUFDb0I7QUFDTztBQUM3QjtBQUNPO0FBQ2lCO0FBQ25CO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sMEJBQTBCLHNEQUFNO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUM7O0FDMU93QjtBQUNJO0FBQ1k7QUFDRTtBQUNBO0FBQ0c7QUFDRjtBQUNBO0FBQ0M7QUFDSTtBQUNmO0FBQ1M7QUFDVjtBQUND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Q3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksa0JBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGtCQUFRO0FBQ3BCO0FBQ0EsZ0JBQWdCLGtCQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsaUJBQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU0sOEVBQThFLE1BQU07QUFDbEc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Qsd0JBQXdCLHlCQUF5QjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQ3JNbUM7QUFDcUI7QUFDZ0I7QUFDdEI7QUFDUjtBQUNWO0FBQzBCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRCxnQkFBZ0I7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRkFBMEYsUUFBUTtBQUNsRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQsUUFBUTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDOztBQzVTd0M7QUFDMEI7QUFDTDtBQUNmO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDTyxNQUFNLFNBQUksU0FBUywrREFBZTtBQUN6QztBQUNBLG1DQUFtQyxTQUFJO0FBQ3ZDO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0M7O0FDbktnRDtBQUNnQjtBQUNTO0FBQ2Q7QUFDb0I7QUFDdkM7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxNQUFNLG9DQUFvQztBQUM5QyxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLFNBQUksU0FBUyx5REFBUztBQUNuQztBQUNBLG1DQUFtQyxTQUFJO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxTQUFJO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEIsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsU0FBSTtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNoWjRDO0FBQ0Y7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLG1CQUFtQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sVUFBVSxpQ0FBZ0I7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDOztBQ3BLOEI7QUFDd0I7QUFDTztBQUNmO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ08sc0JBQXNCLG9EQUFJO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUNsRWdEO0FBQzZCO0FBQ2xCO0FBQzdCO0FBQ1U7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLHVCQUF1Qix5REFBUztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDdFB1QjtBQUNBO0FBQ0c7QUFDQztBQUNDO0FBQzVCLGlDOztBQ0wrQztBQUMyQjtBQUNWO0FBQ1g7QUFDRTtBQUNWO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLG1CQUFTLFNBQVMsNkRBQWE7QUFDNUM7QUFDQSxpREFBaUQsbUJBQVM7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsdUJBQXVCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBLDZDQUE2QyxtQkFBUztBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDekcyRDtBQUNmO0FBQ2tCO0FBQ1o7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sYUFBTSxTQUFTLDZEQUFhO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyx1QkFBdUI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLHVCQUF1QjtBQUM1RDtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsdUJBQXVCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDOztBQ3JFMEM7QUFDSztBQUNHO0FBQ2xEO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyxzREFBTTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNUVvRDtBQUNTO0FBQ3JCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHlCQUF5Qix5REFBUztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDbkVpRDtBQUNnQjtBQUNEO0FBQ1g7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ08sTUFBTSxhQUFNLFNBQVMsMkJBQWE7QUFDekM7QUFDQSw0QkFBNEIsNkJBQW9CLENBQUMsYUFBTTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw2QkFBb0IsQ0FBQyxhQUFNO0FBQ25ELHVCQUF1QixXQUFLO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUN0RHFEO0FBQ1E7QUFDckI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHlCQUF5Qix5REFBUztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUN4Q2lFO0FBQ0Q7QUFDUjtBQUNqQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0saUJBQVEsU0FBUyw2REFBYTtBQUMzQztBQUNBLG1DQUFtQyxpQkFBUTtBQUMzQztBQUNBLDZDQUE2QyxpQkFBUTtBQUNyRCwyQ0FBMkMsdUJBQXVCO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUNsRGtDO0FBQ2tCO0FBQ007QUFDRztBQUNqQjtBQUNrQjtBQUNoQjtBQUNJO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQixzREFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxzQ0FBc0MsdUJBQXVCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUNsSW1EO0FBQ29CO0FBQ2hFLE1BQU0sOEJBQVc7QUFDakI7QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixDQUFDLDhCQUFXO0FBQzdCLDhDOztBQ3hCb0U7QUFDbEM7QUFDVTtBQUNpQjtBQUNDO0FBQ2hCO0FBQ0s7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08seUJBQXlCLHNEQUFNO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGdFQUFnQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUNwRmtDO0FBQzJCO0FBQ1g7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHdCQUF3QixzREFBTTtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNUZpRTtBQUNEO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLFdBQUssU0FBUyw2REFBYTtBQUN4QztBQUNBLG1DQUFtQyxXQUFLO0FBQ3hDO0FBQ0EsNkNBQTZDLFdBQUs7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUM7O0FDN0JpRTtBQUNEO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLFdBQUssU0FBUyw2REFBYTtBQUN4QztBQUNBLG1DQUFtQyxXQUFLO0FBQ3hDO0FBQ0EsNkNBQTZDLFdBQUs7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDOztBQy9Cc0Y7QUFDM0I7QUFDUjtBQUNQO0FBQ087QUFDRDtBQUNsRDtBQUNBO0FBQ0E7QUFDTyxNQUFNLHlCQUFZLFNBQVMsNkRBQWE7QUFDL0M7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHVCQUF1QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxrQ0FBa0Msb0NBQW9DO0FBQ3RFLGtDQUFrQyxvQ0FBb0M7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Qzs7QUM1RDhDO0FBQ0o7QUFDRTtBQUNNO0FBQ0M7QUFDQTtBQUNuRDtBQUNBO0FBQ0E7QUFDTyxNQUFNLHlDQUFvQixTQUFTLDREQUFZO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxxQ0FBcUMsdUJBQXVCO0FBQzVELHFDQUFxQyx1QkFBdUI7QUFDNUQsMENBQTBDLG9DQUFvQztBQUM5RSwwQ0FBMEMsb0NBQW9DO0FBQzlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0Q7O0FDaERzRTtBQUNUO0FBQ2Q7QUFDRDtBQUNJO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08scUJBQXFCLG9FQUFvQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx1Q0FBdUMsdUJBQXVCO0FBQzlELHVDQUF1Qyx1QkFBdUI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0M7O0FDNUo2RDtBQUNYO0FBQ2hCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08seUJBQXlCLHNEQUFNO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQ3BFNEM7QUFDTTtBQUNoQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sNkJBQWMsU0FBUyxzREFBTTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQzs7QUNqQzhDO0FBQ2U7QUFDWDtBQUNBO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLDRCQUE0Qiw4REFBYztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUM7O0FDOUMrQztBQUNpQztBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxtQ0FBaUIsU0FBUyw2REFBYTtBQUNwRDtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsdUJBQXVCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyx1QkFBdUI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLHVCQUF1QjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDOztBQ3JEMEU7QUFDYjtBQUNuQjtBQUNOO0FBQ1U7QUFDSjtBQUNBO0FBQ21CO0FBQ2dCO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLCtCQUErQixzREFBTTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNENBQTRDLHVCQUF1QjtBQUNuRSw4Q0FBOEMsdUJBQXVCO0FBQ3JFLG9DQUFvQyx1QkFBdUI7QUFDM0QsOEJBQThCLHVCQUF1QjtBQUNyRCxxREFBcUQsdUJBQXVCO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Qzs7QUN2RjhDO0FBQ2U7QUFDWDtBQUNSO0FBQ2dDO0FBQzFFO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixnS0FBZ0g7QUFDMUk7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLG9FQUFvQjtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx1QkFBdUIsNERBQVk7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ3ZHOEM7QUFDZTtBQUNyQjtBQUNFO0FBQ2tDO0FBQzFCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qix3R0FBd0Q7QUFDckY7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLDRFQUE0QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsOERBQWM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHVCQUF1Qiw0REFBWTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUNoRzhEO0FBQ1o7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLDJDQUFxQixTQUFTLG9FQUFvQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUQ7O0FDM0JnRTtBQUNIO0FBQ2Y7QUFDSjtBQUNRO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyw0QkFBNEIscUVBQXFCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUNqRWtEO0FBQ1c7QUFDZDtBQUNEO0FBQ2E7QUFDakI7QUFDUTtBQUNrQjtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08seUJBQXlCLDhEQUFjO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLHVCQUF1QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULDBDQUEwQyx1QkFBdUI7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQiw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUMzSThDO0FBQ2U7QUFDZDtBQUNMO0FBQ1E7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDTyxxQkFBcUIsNERBQVk7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLFlBQVk7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUN0SGtDO0FBQ2lCO0FBQ1A7QUFDaUI7QUFDckI7QUFDTjtBQUM4QjtBQUNsQjtBQUNHO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHFCQUFxQixzREFBTTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLFNBQVM7QUFDaEQsdUNBQXVDLFNBQVM7QUFDaEQsc0NBQXNDLFNBQVM7QUFDL0M7QUFDQTtBQUNBLHdDQUF3QyxTQUFTO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0M7O0FDOUdpRTtBQUNqQztBQUNPO0FBQ1U7QUFDQTtBQUNlO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDTyxNQUFNLHlCQUFZLFNBQVMsNkRBQWE7QUFDL0M7QUFDQSxtQ0FBbUMseUJBQVk7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNENBQTRDLHVCQUF1QjtBQUNuRTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDOztBQ2xEaUU7QUFDakM7QUFDTztBQUNVO0FBQ0E7QUFDRjtBQUNpQjtBQUNoRTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNPLE1BQU0seUJBQVksU0FBUyw2REFBYTtBQUMvQztBQUNBLG1DQUFtQyx5QkFBWTtBQUMvQztBQUNBLDhCQUE4Qix1QkFBdUI7QUFDckQsK0JBQStCLHVCQUF1QjtBQUN0RCwrQkFBK0IsdUJBQXVCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxxQ0FBcUMsdUJBQXVCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxnREFBZ0QsdUJBQXVCO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Qzs7QUNwRGtDO0FBQytCO0FBQ0E7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLDJCQUFhLFNBQVMsc0RBQU07QUFDekM7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELHVCQUF1QjtBQUN2RSxnREFBZ0QsdUJBQXVCO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUM7O0FDbER3RDtBQUNkO0FBQ0k7QUFDQTtBQUNlO0FBQ1g7QUFDTTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLDRCQUE0Qiw2REFBYTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx1Q0FBdUMsdUJBQXVCO0FBQzlEO0FBQ0E7QUFDQSw2Q0FBNkMsdUJBQXVCO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx1QkFBdUI7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUM7O0FDaEU4QztBQUNDO0FBQ0g7QUFDRjtBQUNtQjtBQUNYO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQiw0REFBWTtBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxzQ0FBc0MsdUJBQXVCO0FBQzdELHNDQUFzQyx1QkFBdUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0Q7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUNsSWtDO0FBQzJCO0FBQ2Q7QUFDRDtBQUNJO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxzQkFBc0Isc0RBQU07QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUM1RDZCO0FBQ0E7QUFDSDtBQUNHO0FBQ0Q7QUFDSDtBQUNJO0FBQ0c7QUFDRztBQUNSO0FBQ0E7QUFDSztBQUNIO0FBQ0o7QUFDQTtBQUNPO0FBQ047QUFDQTtBQUMxQixpQzs7QUNsQmlFO0FBQ0Q7QUFDdkI7QUFDTTtBQUNhO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGlCQUFRLFNBQVMsNkRBQWE7QUFDM0M7QUFDQSxtQ0FBbUMsaUJBQVE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLGlCQUFRO0FBQ3JELDJEQUEyRCx1QkFBdUI7QUFDbEY7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qiw0QkFBNEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRkFBaUYsS0FBSztBQUN0RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ3ZIaUU7QUFDRDtBQUMxQjtBQUN0QztBQUNBO0FBQ0E7QUFDTyxNQUFNLG1CQUFTLFNBQVMsNkRBQWE7QUFDNUM7QUFDQSxtQ0FBbUMsbUJBQVM7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDOztBQ3RCdUQ7QUFDUztBQUN4QjtBQUNLO0FBQ1A7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLG9CQUFvQix5REFBUztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQzs7QUN6RmlFO0FBQ1Y7QUFDUztBQUN4QjtBQUNPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ08sa0JBQWtCLHlEQUFTO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBHQUEwRyxVQUFVO0FBQ3BIO0FBQ0E7QUFDQTtBQUNBLCtCOztBQ2hFZ0U7QUFDeEI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxzQkFBc0IseURBQVM7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQzlCZ0U7QUFDeEI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDTyx1QkFBdUIseURBQVM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUNyQytDO0FBQ2tCO0FBQ0Q7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sbUJBQW1CLDJCQUFhO0FBQ3ZDO0FBQ0EsY0FBYyw2QkFBb0I7QUFDbEM7QUFDQSx3QkFBd0IsNkJBQW9CO0FBQzVDLHVDQUF1QyxTQUFJO0FBQzNDO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUN4SHFEO0FBQ1k7QUFDRDtBQUM5QjtBQUNBO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxxQkFBcUIsMkJBQWE7QUFDekM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBLHdCQUF3Qiw2QkFBb0I7QUFDNUMsd0NBQXdDLGFBQU07QUFDOUM7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EseUNBQXlDLGFBQU07QUFDL0M7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsa0JBQVE7QUFDaEI7QUFDQTtBQUNBLDZCQUE2Qix1Q0FBeUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUM1RGlFO0FBQ0Q7QUFDbEM7QUFDSTtBQUNtQjtBQUNOO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxzQkFBc0IsMkJBQWE7QUFDMUM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBLHdCQUF3Qiw2QkFBb0I7QUFDNUMsc0NBQXNDLElBQUk7QUFDMUM7QUFDQTtBQUNBLFNBQVM7QUFDVCx5Q0FBeUMsTUFBTTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFFBQVEsa0JBQVE7QUFDaEI7QUFDQTtBQUNBLDZCQUE2Qix1Q0FBeUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0MsU0FBSSxHQUFHLHVCQUF1QjtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsU0FBSTtBQUNqQztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQzNIK0M7QUFDa0I7QUFDRDtBQUNoQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxtQkFBbUIsNkRBQWE7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHVCQUF1QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUM3QitDO0FBQ2tCO0FBQ0Q7QUFDRDtBQUNsQjtBQUNIO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sNkJBQWMsU0FBUyw2REFBYTtBQUNqRDtBQUNBLG1DQUFtQyw2QkFBYztBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLDZDQUE2Qyw2QkFBYztBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQzs7QUN4SGdEO0FBQ2hCO0FBQ3dDO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHVCQUF1QiwyQkFBYTtBQUMzQztBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsV0FBSztBQUNsQztBQUNBO0FBQ0EsU0FBUztBQUNULDZCQUE2QixXQUFLO0FBQ2xDO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNkJBQTZCLFdBQUs7QUFDbEM7QUFDQTtBQUNBLFNBQVM7QUFDVCw0QkFBNEIsV0FBSztBQUNqQztBQUNBO0FBQ0EsU0FBUztBQUNULDRCQUE0QixXQUFLO0FBQ2pDO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNEJBQTRCLFdBQUs7QUFDakM7QUFDQTtBQUNBLFNBQVM7QUFDVCx1QkFBdUIsV0FBSztBQUM1QjtBQUNBO0FBQ0EsU0FBUztBQUNULHVCQUF1QixXQUFLO0FBQzVCO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsdUJBQXVCLFdBQUs7QUFDNUI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLHNDQUFzQyxTQUFTO0FBQy9DLENBQUM7QUFDRCxjQUFjO0FBQ2Q7QUFDQSxDQUFDO0FBQ0Qsb0M7O0FDdEZpRDtBQUNnQjtBQUNEO0FBQzNCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLDZEQUFhO0FBQzNDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ2hMa0M7QUFDK0I7QUFDbEI7QUFDQTtBQUNhO0FBQ0k7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyx1QkFBdUIsNkRBQWE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDbElpRDtBQUNnQjtBQUNEO0FBQ1g7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLHFCQUFVLFNBQVMsMkJBQWE7QUFDN0M7QUFDQSxjQUFjLDZCQUFvQixDQUFDLHFCQUFVO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLHFCQUFVO0FBQ3ZELDZCQUE2QixXQUFLO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULDBCQUEwQixXQUFLO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCwyQkFBMkIsV0FBSztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Qsd0JBQXdCLFdBQUs7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QseUJBQXlCLFdBQUs7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUNsR2lFO0FBQ1Y7QUFDUjtBQUNDO0FBQ2dCO0FBQ0M7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sbUJBQW1CLDZEQUFhO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxnQ0FBZ0MsdUJBQXVCO0FBQ3ZELDhDQUE4Qyx1QkFBdUI7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0M7O0FDdkVpRTtBQUNEO0FBQ3RCO0FBQ1c7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sc0JBQXNCLDZEQUFhO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQzs7QUNsRGlFO0FBQ3ZCO0FBQ3NCO0FBQ1Q7QUFDQTtBQUNGO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxnQ0FBZ0MsNkRBQWE7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2REFBNkQsdUJBQXVCO0FBQ3BGLDhEQUE4RCx1QkFBdUI7QUFDckYsK0RBQStELHVCQUF1QjtBQUN0RixpRUFBaUUsdUJBQXVCO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDOztBQ25EaUU7QUFDdkI7QUFDc0I7QUFDWDtBQUNNO0FBQ1o7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLGtDQUFrQyw2REFBYTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxpQ0FBaUMsdUJBQXVCO0FBQ3hELCtEQUErRCx1QkFBdUI7QUFDdEYsK0RBQStELHVCQUF1QjtBQUN0RixpRUFBaUUsdUJBQXVCO0FBQ3hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQzs7QUM5RStDO0FBQ2tCO0FBQ0Q7QUFDRDtBQUNKO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ08sa0JBQWtCLDZEQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyx1QkFBdUI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCOztBQ2hGa0M7QUFDK0I7QUFDSTtBQUNMO0FBQ2pCO0FBQ0U7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHdCQUF3Qiw2REFBYTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULGdDQUFnQyx1QkFBdUI7QUFDdkQsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDOztBQ3ZHb0M7QUFDSDtBQUNGO0FBQ0k7QUFDQztBQUNBO0FBQ0Y7QUFDRTtBQUNKO0FBQ087QUFDQTtBQUNSO0FBQ1U7QUFDUjtBQUNFO0FBQ0Y7QUFDRTtBQUNKO0FBQ0M7QUFDQztBQUNLO0FBQ047QUFDRztBQUNVO0FBQ0U7QUFDRjtBQUNUO0FBQ1M7QUFDaEI7QUFDRztBQUNPO0FBQ0s7QUFDRDtBQUNSO0FBQ0c7QUFDdEMsaUM7O0FDbkM2QjtBQUNFO0FBQ0E7QUFDSTtBQUNMO0FBQ0M7QUFDRztBQUNsQyxtQzs7QUNQdUQ7QUFDN0I7QUFDQTtBQUNpQjtBQUNzQjtBQUMzQjtBQUNrQjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLGFBQVMsR0FBRyxpQkFBVTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sZUFBVyxHQUFHLGlCQUFVO0FBQ3JDO0FBQ0E7QUFDQTtBQUNPLGVBQWUsaUJBQVU7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxZQUFRLEdBQUcsaUJBQVU7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxRQUFJLEdBQUcsaUJBQVU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxnQkFBZ0IsaUJBQVU7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ21FO0FBQ0M7QUFDN0QsZUFBZSwrREFBZTtBQUM5QixnQkFBZ0IsZ0VBQWdCO0FBQ2hDLHFCQUFxQixnRUFBZ0I7QUFDNUMsaUM7Ozs7O0FDckc2QjtBQUN1QjtBQUVwRCxJQUFNRSxRQUFRLEdBQ1pDLFNBQVMsQ0FBQ0MsU0FBUyxDQUFDQyxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUlGLFNBQVMsQ0FBQ0MsU0FBUyxDQUFDQyxLQUFLLENBQUMsT0FBTyxDQUFDO0FBQzVFLElBQU1DLE1BQU0sR0FBR0gsU0FBUyxDQUFDQyxTQUFTLENBQUNDLEtBQUssQ0FBQyxPQUFPLENBQUM7QUFDakQsSUFBTUUsU0FBUyxHQUFHSixTQUFTLENBQUNDLFNBQVMsQ0FBQ0MsS0FBSyxDQUFDLFVBQVUsQ0FBQztBQUN2RCxJQUFNRyxRQUFRLEdBQUdOLFFBQVEsSUFBSUksTUFBTSxJQUFJQyxTQUFTO0FBQ2hELElBQU1FLFNBQVMsR0FBRyxDQUFDRCxRQUFRO0FBRTNCRSxRQUFRLENBQUNDLElBQUksQ0FBQ0MsU0FBUyxDQUFDQyxHQUFHLENBQUNMLFFBQVEsR0FBRyxRQUFRLEdBQUcsU0FBUyxDQUFDO0FBRXJELElBQU1NLE9BQU8sR0FBRztFQUFFWixRQUFRLEVBQVJBLFFBQVE7RUFBRUksTUFBTSxFQUFOQSxNQUFNO0VBQUVFLFFBQVEsRUFBUkEsUUFBUTtFQUFFQyxTQUFTLEVBQVRBO0FBQVUsQ0FBQztBQUN6RCxJQUFNTSxNQUFNLEdBQUcsU0FBVEEsTUFBTUEsQ0FBSUMsQ0FBQztFQUFBLE9BQUtBLENBQUMsQ0FBQ0MsSUFBSSxDQUFDQyxLQUFLLENBQUNELElBQUksQ0FBQ0UsTUFBTSxDQUFDLENBQUMsR0FBR0gsQ0FBQyxDQUFDSSxNQUFNLENBQUMsQ0FBQztBQUFBO0FBQzdELElBQU1DLEdBQUcsR0FBRyxTQUFOQSxHQUFHQSxDQUFJQyxDQUFDLEVBQUVDLENBQUM7RUFBQSxPQUFLRCxDQUFDLEdBQUdDLENBQUMsR0FBR04sSUFBSSxDQUFDQyxLQUFLLENBQUNJLENBQUMsR0FBR0MsQ0FBQyxDQUFDO0FBQUE7QUFDL0MsSUFBTUosTUFBTSxHQUFHLFNBQVRBLE1BQU1BLENBQUE7RUFBQSxPQUFTRixJQUFJLENBQUNFLE1BQU0sQ0FBQyxDQUFDO0FBQUE7QUFDbEMsSUFBTUssSUFBSSxHQUFHLFNBQVBBLElBQUlBLENBQUlGLENBQUM7RUFBQSxPQUFLTCxJQUFJLENBQUNFLE1BQU0sQ0FBQyxDQUFDLEdBQUdHLENBQUM7QUFBQTtBQUNyQyxJQUFNRyxPQUFPLEdBQUcsU0FBVkEsT0FBT0EsQ0FBSUgsQ0FBQztFQUFBLE9BQUtFLElBQUksQ0FBQ0YsQ0FBQyxDQUFDLEdBQUcsQ0FBQztBQUFBO0FBQ2xDLElBQU1JLGNBQVMsR0FBRyxTQUFaQSxTQUFTQSxDQUFJVixDQUFDLEVBQUVXLENBQUM7RUFBQSxPQUFLWCxDQUFDLEdBQUdRLElBQUksQ0FBQ0csQ0FBQyxHQUFHWCxDQUFDLENBQUM7QUFBQTtBQUMzQyxJQUFNWSxRQUFRLEdBQUcsU0FBWEEsUUFBUUEsQ0FBQTtFQUFBLE9BQVVULE1BQU0sQ0FBQyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUM7QUFBQSxDQUFDO0FBQ2pELElBQU1VLFlBQVksR0FBRyxTQUFmQSxZQUFZQSxDQUFBLEVBQVM7RUFDaEMsSUFBSUMsQ0FBQyxHQUFHWCxNQUFNLENBQUMsQ0FBQztFQUNoQixPQUFPVyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHQSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDO0FBQzNDLENBQUM7QUFFTSxTQUFTQyxtQkFBbUJBLENBQUNDLEVBQUUsRUFBRTtFQUN0QyxJQUFNQyxTQUFTLEdBQUd2QixRQUFRLENBQUN3QixhQUFhLENBQUMsS0FBSyxDQUFDO0VBQy9DLElBQU1DLE1BQU0sR0FBR3pCLFFBQVEsQ0FBQ3dCLGFBQWEsQ0FBQyxLQUFLLENBQUM7RUFDNUNDLE1BQU0sQ0FBQ0MsU0FBUyxHQUFHLDBDQUEwQztFQUM3REMsTUFBTSxDQUFDQyxNQUFNLENBQUNMLFNBQVMsQ0FBQ00sS0FBSyxFQUFFO0lBQzdCQyxPQUFPLEVBQUUsT0FBTztJQUNoQkMsUUFBUSxFQUFFLFVBQVU7SUFDcEJDLEtBQUssRUFBRSxNQUFNO0lBQ2JDLE1BQU0sRUFBRSxNQUFNO0lBQ2RDLE1BQU0sRUFBRSxPQUFPO0lBQ2ZDLEdBQUcsRUFBRSxLQUFLO0lBQ1ZDLElBQUksRUFBRSxLQUFLO0lBQ1hDLGVBQWUsRUFBRTtFQUNuQixDQUFDLENBQUM7RUFDRlYsTUFBTSxDQUFDQyxNQUFNLENBQUNILE1BQU0sQ0FBQ0ksS0FBSyxFQUFFO0lBQzFCQyxPQUFPLEVBQUUsT0FBTztJQUNoQkMsUUFBUSxFQUFFLFVBQVU7SUFDcEJLLElBQUksRUFBRSxLQUFLO0lBQ1hELEdBQUcsRUFBRSxLQUFLO0lBQ1ZHLE9BQU8sRUFBRSxNQUFNO0lBQ2ZELGVBQWUsRUFBRSxTQUFTO0lBQzFCRSxLQUFLLEVBQUUsT0FBTztJQUNkQyxVQUFVLEVBQUUsb0JBQW9CO0lBQ2hDQyxZQUFZLEVBQUUsS0FBSztJQUNuQkMsU0FBUyxFQUFFLDBCQUEwQjtJQUNyQ0MsU0FBUyxFQUFFLFFBQVE7SUFDbkJDLFVBQVUsRUFBRSxLQUFLO0lBQ2pCWixLQUFLLEVBQUUsT0FBTztJQUNkYSxNQUFNLEVBQUU7RUFDVixDQUFDLENBQUM7RUFDRnRCLFNBQVMsQ0FBQ3VCLFdBQVcsQ0FBQ3JCLE1BQU0sQ0FBQztFQUM3QnpCLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDNkMsV0FBVyxDQUFDdkIsU0FBUyxDQUFDO0VBQ3BDaEMsc0NBQTRCLENBQUNELE9BQVksQ0FBQztFQUMxQ0MsOEJBQW9CLENBQUNrQyxNQUFNLENBQUM7RUFDNUJsQyxxQ0FBMkIsQ0FBQyxVQUFDNEQsQ0FBQyxFQUFLO0lBQ2pDNUIsU0FBUyxDQUFDNkIsTUFBTSxDQUFDLENBQUM7SUFDbEI5QixFQUFFLENBQUMsQ0FBQztFQUNOLENBQUMsQ0FBQztBQUNKLEM7Ozs7Ozs7Ozs7Ozs7OztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUhBLElBS3FCK0IsWUFBWTtFQUMvQjtBQUNGO0FBQ0E7RUFDRSxTQUFBQSxhQUFBQyxJQUFBLEVBQWdDO0lBQUEsSUFBbEJDLE1BQU0sR0FBQUQsSUFBQSxDQUFOQyxNQUFNO01BQUVDLE1BQU0sR0FBQUYsSUFBQSxDQUFORSxNQUFNO0lBQUFDLGVBQUEsT0FBQUosWUFBQTtJQUMxQixJQUFJLENBQUNFLE1BQU0sR0FBR0EsTUFBTTtJQUNwQixJQUFJLENBQUN0QixNQUFNLEdBQUcsR0FBRztJQUNqQixJQUFJLENBQUN5QixTQUFTLEdBQUcsQ0FBQztJQUNsQixJQUFJLENBQUNDLGNBQWMsR0FBRyxDQUFDO0lBQ3ZCLElBQUksQ0FBQ0MsZUFBZSxHQUFHLENBQUM7O0lBRXhCO0lBQ0EsSUFBSSxDQUFDQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUM7O0lBRWxCO0lBQ0EsSUFBSSxDQUFDQyxXQUFXLEdBQUcsRUFBRTs7SUFFckI7SUFDQSxJQUFJLENBQUNDLFlBQVksQ0FBQ1AsTUFBTSxDQUFDO0lBQ3pCO0lBQ0EsSUFBSSxDQUFDUSxNQUFNLEdBQUcsSUFBSUMsS0FBSyxDQUFDQyxNQUFNLENBQUNDLFVBQVUsQ0FBQyxDQUFDQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2xELElBQUksQ0FBQ0MsS0FBSyxHQUFHLEVBQUU7SUFDZixJQUFJLENBQUNDLE1BQU0sQ0FBQyxFQUFFLENBQUM7O0lBRWY7SUFDQSxJQUFJLENBQUNDLE1BQU0sQ0FBQyxDQUFDOztJQUViO0lBQ0EsSUFBSSxDQUFDQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUM7RUFDL0I7O0VBRUE7QUFDRjtBQUNBO0VBRkVDLFlBQUEsQ0FBQXBCLFlBQUE7SUFBQXFCLEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFaLGFBQWFQLE1BQU0sRUFBRTtNQUNuQixJQUFJLENBQUNBLE1BQU0sR0FBR0EsTUFBTSxJQUFJeEQsUUFBUSxDQUFDQyxJQUFJO01BQ3JDLElBQUksQ0FBQzJFLE1BQU0sR0FBRyxJQUFJLENBQUNBLE1BQU0sSUFBSTVFLFFBQVEsQ0FBQ3dCLGFBQWEsQ0FBQyxRQUFRLENBQUM7TUFDN0QsSUFBSSxDQUFDcUQsR0FBRyxHQUFHLElBQUksQ0FBQ0EsR0FBRyxJQUFJLElBQUksQ0FBQ0QsTUFBTSxDQUFDRSxVQUFVLENBQUMsSUFBSSxDQUFDO01BQ25ELElBQUksQ0FBQ3RCLE1BQU0sQ0FBQ1YsV0FBVyxDQUFDLElBQUksQ0FBQzhCLE1BQU0sQ0FBQztJQUN0Qzs7SUFFQTtBQUNGO0FBQ0E7RUFGRTtJQUFBRixHQUFBO0lBQUFDLEtBQUEsWUFBQUksc0JBQUE7TUFBQSxTQUFBUCxzQkFBQVEsRUFBQTtRQUFBLE9BQUFELHNCQUFBLENBQUFFLEtBQUEsT0FBQUMsU0FBQTtNQUFBO01BQUFWLHFCQUFBLENBQUFXLFFBQUE7UUFBQSxPQUFBSixzQkFBQSxDQUFBSSxRQUFBO01BQUE7TUFBQSxPQUFBWCxxQkFBQTtJQUFBLEVBR0EsVUFBc0JZLEtBQUssRUFBRTtNQUFBLElBQUFDLEtBQUE7TUFDM0JiLHFCQUFxQixDQUFDLFVBQUNZLEtBQUssRUFBSztRQUMvQkMsS0FBSSxDQUFDYixxQkFBcUIsQ0FBQ1ksS0FBSyxDQUFDO01BQ25DLENBQUMsQ0FBQztNQUNGLElBQUksQ0FBQ0UsS0FBSyxDQUFDRixLQUFLLENBQUM7TUFDakIsSUFBSSxDQUFDMUIsU0FBUyxHQUFHMEIsS0FBSztJQUN4Qjs7SUFFQTtBQUNGO0FBQ0EsT0FGRTtFQUFBO0lBQUFWLEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFKLE9BQUEsRUFBUztNQUNQLElBQUksQ0FBQ0ssTUFBTSxDQUFDNUMsS0FBSyxHQUFHa0MsTUFBTSxDQUFDQyxVQUFVO01BQ3JDLElBQUksQ0FBQ1MsTUFBTSxDQUFDM0MsTUFBTSxHQUFHLElBQUksQ0FBQ0EsTUFBTTtJQUNsQzs7SUFFQTtBQUNGO0FBQ0E7RUFGRTtJQUFBeUMsR0FBQTtJQUFBQyxLQUFBLEVBR0EsU0FBQVksTUFBQSxFQUFRO01BQ04sSUFBSSxDQUFDVixHQUFHLENBQUNXLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQ1osTUFBTSxDQUFDNUMsS0FBSyxFQUFFLElBQUksQ0FBQzRDLE1BQU0sQ0FBQzNDLE1BQU0sQ0FBQztJQUNqRTs7SUFFQTtBQUNGO0FBQ0E7RUFGRTtJQUFBeUMsR0FBQTtJQUFBQyxLQUFBLEVBR0EsU0FBQUwsT0FBT21CLElBQUksRUFBRXpCLE1BQU0sRUFBRUssS0FBSyxFQUFFO01BQzFCLElBQUksQ0FBQ1YsY0FBYyxHQUFHOEIsSUFBSTtNQUMxQixJQUFJLENBQUM3QixlQUFlLEdBQUcsSUFBSSxDQUFDRixTQUFTO01BQ3JDLElBQUksQ0FBQ00sTUFBTSxHQUFHLElBQUksQ0FBQ0EsTUFBTSxDQUN0QjBCLE1BQU0sQ0FBQyxVQUFDZixLQUFLO1FBQUEsT0FBS0EsS0FBSyxJQUFJQSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUdjLElBQUk7TUFBQSxFQUFDLENBQzNDRSxNQUFNLENBQUMzQixNQUFNLENBQUMsQ0FDZDRCLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQ2hCLE1BQU0sQ0FBQzVDLEtBQUssQ0FBQyxDQUN6QjZELElBQUksQ0FBQyxVQUFDdkYsQ0FBQyxFQUFFVyxDQUFDO1FBQUEsT0FBS1gsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHVyxDQUFDLENBQUMsQ0FBQyxDQUFDO01BQUEsRUFBQztNQUU5QixJQUFJb0QsS0FBSyxhQUFMQSxLQUFLLGVBQUxBLEtBQUssQ0FBRTNELE1BQU0sRUFBRTtRQUNqQixJQUFJLENBQUMyRCxLQUFLLEdBQUcsSUFBSSxDQUFDQSxLQUFLLENBQ3BCc0IsTUFBTSxDQUFDdEIsS0FBSyxDQUFDLENBQ2J1QixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FDVkMsSUFBSSxDQUFDLFVBQUN2RixDQUFDLEVBQUVXLENBQUM7VUFBQSxPQUFLWCxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUdXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFBQSxFQUFDO01BQ2hDO0lBQ0Y7O0lBRUE7QUFDRjtBQUNBO0VBRkU7SUFBQXlELEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFXLE1BQU1GLEtBQUssRUFBRTtNQUNYLElBQUksQ0FBQ0csS0FBSyxDQUFDLENBQUM7TUFDWixJQUFJLENBQUNPLGNBQWMsQ0FBQ1YsS0FBSyxDQUFDO01BQzFCLElBQUksQ0FBQ1csVUFBVSxDQUFDLENBQUM7TUFDakIsSUFBSSxDQUFDQyxTQUFTLENBQUNaLEtBQUssQ0FBQztJQUN2Qjs7SUFFQTtBQUNGO0FBQ0E7RUFGRTtJQUFBVixHQUFBO0lBQUFDLEtBQUEsRUFHQSxTQUFBb0IsV0FBQSxFQUFhO01BQ1gsSUFBUW5CLE1BQU0sR0FBVSxJQUFJLENBQXBCQSxNQUFNO1FBQUVDLEdBQUcsR0FBSyxJQUFJLENBQVpBLEdBQUc7TUFDbkIsSUFBUTdDLEtBQUssR0FBYTRDLE1BQU0sQ0FBeEI1QyxLQUFLO1FBQUVDLE1BQU0sR0FBSzJDLE1BQU0sQ0FBakIzQyxNQUFNOztNQUVyQjtNQUFBLElBQUFnRSxTQUFBLEdBQUFDLDBCQUFBLENBQ29CLElBQUksQ0FBQzNDLE1BQU0sQ0FBQzRDLE1BQU07UUFBQUMsS0FBQTtNQUFBO1FBQXRDLEtBQUFILFNBQUEsQ0FBQUksQ0FBQSxNQUFBRCxLQUFBLEdBQUFILFNBQUEsQ0FBQXJGLENBQUEsSUFBQTBGLElBQUEsR0FBd0M7VUFBQSxJQUE3QkMsS0FBSyxHQUFBSCxLQUFBLENBQUF6QixLQUFBO1VBQ2QsSUFBTTZCLENBQUMsR0FBR0MsYUFBYSxDQUFDRixLQUFLLENBQUNHLEtBQUssRUFBRXpFLE1BQU0sQ0FBQztVQUU1QzRDLEdBQUcsQ0FBQzhCLFNBQVMsQ0FBQyxDQUFDO1VBQ2Y5QixHQUFHLENBQUMrQixXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7VUFDdkIvQixHQUFHLENBQUNnQyxTQUFTLEdBQUcsQ0FBQztVQUNqQmhDLEdBQUcsQ0FBQ2lDLFdBQVcsR0FBR1AsS0FBSyxDQUFDaEUsS0FBSyxJQUFJLE1BQU07VUFDdkNzQyxHQUFHLENBQUNrQyxNQUFNLENBQUMsQ0FBQyxFQUFFUCxDQUFDLENBQUM7VUFDaEIzQixHQUFHLENBQUNtQyxNQUFNLENBQUNoRixLQUFLLEVBQUV3RSxDQUFDLENBQUM7VUFDcEIzQixHQUFHLENBQUNvQyxNQUFNLENBQUMsQ0FBQztRQUNkOztRQUVBO01BQUEsU0FBQUMsR0FBQTtRQUFBakIsU0FBQSxDQUFBa0IsQ0FBQSxDQUFBRCxHQUFBO01BQUE7UUFBQWpCLFNBQUEsQ0FBQW1CLENBQUE7TUFBQTtNQUNBdkMsR0FBRyxDQUFDOEIsU0FBUyxDQUFDLENBQUM7TUFDZjlCLEdBQUcsQ0FBQytCLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztNQUN2Qi9CLEdBQUcsQ0FBQ2dDLFNBQVMsR0FBRyxDQUFDO01BQ2pCaEMsR0FBRyxDQUFDaUMsV0FBVyxHQUFHLE1BQU07TUFDeEJqQyxHQUFHLENBQUNrQyxNQUFNLENBQUMvRSxLQUFLLEdBQUcsSUFBSSxDQUFDOEIsV0FBVyxFQUFFLENBQUMsQ0FBQztNQUN2Q2UsR0FBRyxDQUFDbUMsTUFBTSxDQUFDaEYsS0FBSyxHQUFHLElBQUksQ0FBQzhCLFdBQVcsRUFBRTdCLE1BQU0sQ0FBQztNQUM1QzRDLEdBQUcsQ0FBQ29DLE1BQU0sQ0FBQyxDQUFDO0lBQ2Q7O0lBRUE7QUFDRjtBQUNBO0VBRkU7SUFBQXZDLEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFtQixlQUFlVixLQUFLLEVBQUU7TUFDcEIsSUFBUVIsTUFBTSxHQUFVLElBQUksQ0FBcEJBLE1BQU07UUFBRUMsR0FBRyxHQUFLLElBQUksQ0FBWkEsR0FBRztNQUNuQixJQUFRN0MsS0FBSyxHQUFhNEMsTUFBTSxDQUF4QjVDLEtBQUs7UUFBRUMsTUFBTSxHQUFLMkMsTUFBTSxDQUFqQjNDLE1BQU07TUFFckIsSUFBTW9GLFVBQVUsR0FBRyxJQUFJLENBQUNyRCxNQUFNLENBQUN0RCxNQUFNO01BQ3JDLElBQUk0RyxLQUFLLEdBQUcsQ0FBQzs7TUFFYjtNQUNBekMsR0FBRyxDQUFDOEIsU0FBUyxDQUFDLENBQUM7TUFDZjlCLEdBQUcsQ0FBQ2lDLFdBQVcsR0FBRyxNQUFNO01BQ3hCakMsR0FBRyxDQUFDZ0MsU0FBUyxHQUFHLEdBQUc7TUFDbkJoQyxHQUFHLENBQUMrQixXQUFXLENBQUMsRUFBRSxDQUFDOztNQUVuQjtNQUNBLElBQU1XLFdBQVcsR0FBRyxDQUFDbkMsS0FBSyxHQUFHLElBQUksQ0FBQ3hCLGVBQWUsSUFBSSxJQUFJOztNQUV6RDtNQUFBLElBQUE0RCxVQUFBLEdBQUF0QiwwQkFBQSxDQUNvQixJQUFJLENBQUNsQyxNQUFNO1FBQUF5RCxNQUFBO01BQUE7UUFBL0IsS0FBQUQsVUFBQSxDQUFBbkIsQ0FBQSxNQUFBb0IsTUFBQSxHQUFBRCxVQUFBLENBQUE1RyxDQUFBLElBQUEwRixJQUFBLEdBQWlDO1VBQUEsSUFBdEJvQixLQUFLLEdBQUFELE1BQUEsQ0FBQTlDLEtBQUE7VUFDZCxJQUFJLENBQUMrQyxLQUFLLEVBQUU7WUFDVkosS0FBSyxJQUFJLENBQUM7WUFDVjtVQUNGO1VBRUEsSUFBQUssTUFBQSxHQUFBQyxjQUFBLENBQXNCRixLQUFLO1lBQXBCakMsSUFBSSxHQUFBa0MsTUFBQTtZQUFFaEQsS0FBSyxHQUFBZ0QsTUFBQTs7VUFFbEI7VUFDQTtVQUNBO1VBQ0EsSUFBTUUsVUFBVSxHQUFHLElBQUksQ0FBQ2xFLGNBQWMsR0FBRzRELFdBQVcsR0FBRzlCLElBQUk7VUFFM0QsSUFBTXFDLENBQUMsR0FBRzlGLEtBQUssR0FBRzZGLFVBQVUsR0FBRyxJQUFJLENBQUNoRSxLQUFLLEdBQUc3QixLQUFLLEdBQUcsSUFBSSxDQUFDOEIsV0FBVztVQUNwRSxJQUFNMEMsQ0FBQyxHQUFHQyxhQUFhLENBQUM5QixLQUFLLEVBQUUxQyxNQUFNLENBQUM7VUFFdEMsSUFBSTZGLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDVDtVQUNGO1VBRUEsSUFBSVIsS0FBSyxLQUFLLENBQUMsRUFBRTtZQUNmekMsR0FBRyxDQUFDa0MsTUFBTSxDQUFDZSxDQUFDLEVBQUV0QixDQUFDLENBQUM7VUFDbEI7VUFDQTNCLEdBQUcsQ0FBQ21DLE1BQU0sQ0FBQ2MsQ0FBQyxFQUFFdEIsQ0FBQyxDQUFDO1VBQ2hCYyxLQUFLLElBQUksQ0FBQztRQUNaOztRQUVBO01BQUEsU0FBQUosR0FBQTtRQUFBTSxVQUFBLENBQUFMLENBQUEsQ0FBQUQsR0FBQTtNQUFBO1FBQUFNLFVBQUEsQ0FBQUosQ0FBQTtNQUFBO01BQ0F2QyxHQUFHLENBQUNvQyxNQUFNLENBQUMsQ0FBQztJQUNkOztJQUVBO0FBQ0Y7QUFDQTtFQUZFO0lBQUF2QyxHQUFBO0lBQUFDLEtBQUEsRUFHQSxTQUFBcUIsVUFBVVosS0FBSyxFQUFFO01BQ2YsSUFBUVIsTUFBTSxHQUFVLElBQUksQ0FBcEJBLE1BQU07UUFBRUMsR0FBRyxHQUFLLElBQUksQ0FBWkEsR0FBRztNQUNuQixJQUFRN0MsS0FBSyxHQUFhNEMsTUFBTSxDQUF4QjVDLEtBQUs7UUFBRUMsTUFBTSxHQUFLMkMsTUFBTSxDQUFqQjNDLE1BQU07O01BRXJCO01BQ0EsSUFBTXNGLFdBQVcsR0FBRyxDQUFDbkMsS0FBSyxHQUFHLElBQUksQ0FBQ3hCLGVBQWUsSUFBSSxJQUFJOztNQUV6RDtNQUFBLElBQUFtRSxVQUFBLEdBQUE3QiwwQkFBQSxDQUNtQixJQUFJLENBQUM3QixLQUFLO1FBQUEyRCxNQUFBO01BQUE7UUFBN0IsS0FBQUQsVUFBQSxDQUFBMUIsQ0FBQSxNQUFBMkIsTUFBQSxHQUFBRCxVQUFBLENBQUFuSCxDQUFBLElBQUEwRixJQUFBLEdBQStCO1VBQUEsSUFBcEIyQixJQUFJLEdBQUFELE1BQUEsQ0FBQXJELEtBQUE7VUFDYixJQUFBdUQsS0FBQSxHQUFBTixjQUFBLENBQWlDSyxJQUFJO1lBQTlCeEMsSUFBSSxHQUFBeUMsS0FBQTtZQUFFdkQsS0FBSyxHQUFBdUQsS0FBQTtZQUFFQyxTQUFTLEdBQUFELEtBQUE7VUFDN0IsSUFBTUwsVUFBVSxHQUFHLElBQUksQ0FBQ2xFLGNBQWMsR0FBRzRELFdBQVcsR0FBRzlCLElBQUk7VUFDM0QsSUFBTXFDLENBQUMsR0FBRzlGLEtBQUssR0FBRzZGLFVBQVUsR0FBRyxJQUFJLENBQUNoRSxLQUFLLEdBQUc3QixLQUFLLEdBQUcsSUFBSSxDQUFDOEIsV0FBVztVQUNwRSxJQUFNMEMsQ0FBQyxHQUFHQyxhQUFhLENBQUM5QixLQUFLLEVBQUUxQyxNQUFNLENBQUM7O1VBRXRDO1VBQ0EsSUFBSTZGLENBQUMsR0FBRzlGLEtBQUssR0FBRyxJQUFJLENBQUM4QixXQUFXLEVBQUU7WUFDaEM7VUFDRjs7VUFFQTtVQUNBLElBQU1zRSxPQUFPLEdBQUcsQ0FBQyxHQUFJUCxVQUFVLEdBQUcsSUFBSSxDQUFDaEUsS0FBSyxHQUFHN0IsS0FBSyxHQUFJLElBQUk7VUFDNUQsSUFBSW9HLE9BQU8sR0FBRyxLQUFLLEVBQUU7WUFDbkI7VUFDRjtVQUNBdkQsR0FBRyxDQUFDOEIsU0FBUyxDQUFDLENBQUM7VUFDZjlCLEdBQUcsQ0FBQ3dELEdBQUcsQ0FBQ1AsQ0FBQyxHQUFHLEdBQUcsRUFBRXRCLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBR2pHLElBQUksQ0FBQytILEVBQUUsQ0FBQztVQUN0Q3pELEdBQUcsQ0FBQzBELFNBQVMsR0FBR0osU0FBUyx1QkFBQXhDLE1BQUEsQ0FDRHlDLE9BQU8sNkJBQUF6QyxNQUFBLENBQ1B5QyxPQUFPLE1BQUc7VUFDbEN2RCxHQUFHLENBQUNULElBQUksQ0FBQyxDQUFDO1FBQ1o7TUFBQyxTQUFBOEMsR0FBQTtRQUFBYSxVQUFBLENBQUFaLENBQUEsQ0FBQUQsR0FBQTtNQUFBO1FBQUFhLFVBQUEsQ0FBQVgsQ0FBQTtNQUFBO0lBQ0g7RUFBQztFQUFBLE9BQUEvRCxZQUFBO0FBQUE7QUFHSDtBQUNBO0FBQ0E7QUF6TmlDO0FBME5qQyxJQUFNb0QsYUFBYSxHQUFHLFNBQWhCQSxhQUFhQSxDQUFJOUIsS0FBSyxFQUFFMUMsTUFBTTtFQUFBLE9BQU0sQ0FBQzBDLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFJMUMsTUFBTTtBQUFBLEU7Ozs7Ozs7Ozs7Ozs7O0FDL05uRTtBQUNBO0FBQ0E7O0FBRTZCO0FBQ087QUFFcEMsSUFBTXdHLE1BQU0sR0FBRyxDQUFDLEdBQUdsSSxJQUFJLENBQUMrSCxFQUFFOztBQUUxQjtBQUNBO0FBQ0E7QUFDQSxJQUFNSSxXQUFXLEdBQUc7RUFDbEJDLElBQUksRUFBRXBJLElBQUksQ0FBQ3FJLEdBQUc7RUFDZEMsUUFBUSxFQUFFLFNBQUFBLFNBQUNwRCxJQUFJO0lBQUEsT0FDWixDQUFDLEdBQUdnRCxNQUFNLEdBQ1RsSSxJQUFJLENBQUN1SSxHQUFHLENBQ0wsQ0FBRSxDQUFDckQsSUFBSSxHQUFHZ0QsTUFBTSxHQUFHLENBQUMsSUFBSUEsTUFBTSxHQUFJQSxNQUFNLElBQUlBLE1BQU0sR0FBSUEsTUFBTSxHQUFHLENBQ2xFLENBQUMsR0FDSCxDQUFDO0VBQUE7RUFDSE0sTUFBTSxFQUFFLFNBQUFBLE9BQUN0RCxJQUFJO0lBQUEsT0FBTUEsSUFBSSxHQUFHZ0QsTUFBTSxHQUFHbEksSUFBSSxDQUFDK0gsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7RUFBQSxDQUFDO0VBQ3BEVSxHQUFHLEVBQUUsU0FBQUEsSUFBQ3ZELElBQUk7SUFBQSxPQUFLLENBQUVBLElBQUksR0FBR2dELE1BQU0sR0FBSWxJLElBQUksQ0FBQytILEVBQUUsSUFBSS9ILElBQUksQ0FBQytILEVBQUU7RUFBQTtBQUN0RCxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUZBLElBR3FCVyxNQUFNO0VBQ3pCO0FBQ0Y7QUFDQTtFQUNFLFNBQUFBLE9BQUEzRixJQUFBLEVBQXVDO0lBQUEsSUFBekI0RixLQUFLLEdBQUE1RixJQUFBLENBQUw0RixLQUFLO01BQUUvQyxNQUFNLEdBQUE3QyxJQUFBLENBQU42QyxNQUFNO01BQUUzQyxNQUFNLEdBQUFGLElBQUEsQ0FBTkUsTUFBTTtJQUFBQyxxQkFBQSxPQUFBd0YsTUFBQTtJQUNqQyxJQUFJLENBQUNFLFVBQVUsR0FBRyxDQUFDO0lBQ25CLElBQUksQ0FBQ0MsS0FBSyxHQUFHLEVBQUU7SUFDZixJQUFJLENBQUNGLEtBQUssR0FBR0EsS0FBSyxJQUFJLENBQ3BCO01BQUVHLEtBQUssRUFBRSxVQUFVO01BQUVDLFNBQVMsRUFBRXRJLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRztJQUFFLENBQUMsRUFDckQ7TUFBRXFJLEtBQUssRUFBRSxVQUFVO01BQUVDLFNBQVMsRUFBRXRJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSTtJQUFFLENBQUMsRUFDdkQ7TUFBRXFJLEtBQUssRUFBRSxVQUFVO01BQUVDLFNBQVMsRUFBRXRJLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUFFLENBQUMsRUFDakQ7TUFBRXFJLEtBQUssRUFBRSxVQUFVO01BQUVDLFNBQVMsRUFBRXRJLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUFFLENBQUMsQ0FDbEQ7SUFDRCxJQUFJLENBQUNtRixNQUFNLEdBQUdBLE1BQU07SUFDcEIsSUFBSSxDQUFDb0QsYUFBYSxHQUFHLElBQUk7SUFDekIsSUFBSSxDQUFDM0UsTUFBTSxHQUFHLElBQUl2QixZQUFZLENBQUM7TUFBRUUsTUFBTSxFQUFFLElBQUk7TUFBRUMsTUFBTSxFQUFOQTtJQUFPLENBQUMsQ0FBQztFQUMxRDs7RUFFQTtBQUNGO0FBQ0E7RUFGRWlCLGtCQUFBLENBQUF3RSxNQUFBO0lBQUF2RSxHQUFBO0lBQUFDLEtBQUEsRUFHQSxTQUFBNkUsTUFBQSxFQUFRO01BQUEsSUFBQW5FLEtBQUE7TUFDTm9FLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDLGNBQWMsQ0FBQztNQUMzQixJQUFJLENBQUNDLElBQUksQ0FBQyxDQUFDO01BQ1gsSUFBSSxDQUFDQyxLQUFLLEdBQUcsSUFBSXRLLFdBQVUsQ0FBQyxVQUFDbUcsSUFBSSxFQUFLO1FBQ3BDLElBQU16QixNQUFNLEdBQUdxQixLQUFJLENBQUN5RSxRQUFRLENBQUNyRSxJQUFJLENBQUM7UUFDbEMsSUFBTXBCLEtBQUssR0FBR2dCLEtBQUksQ0FBQzBFLElBQUksQ0FBQy9GLE1BQU0sQ0FBQztRQUMvQnFCLEtBQUksQ0FBQ1QsTUFBTSxDQUFDTixNQUFNLENBQUNtQixJQUFJLEVBQUV6QixNQUFNLEVBQUVLLEtBQUssQ0FBQztNQUN6QyxDQUFDLEVBQUUsSUFBSSxDQUFDOEUsVUFBVSxDQUFDO01BQ25CLElBQUksQ0FBQ1MsS0FBSyxDQUFDSixLQUFLLENBQUMsQ0FBQztJQUNwQjs7SUFFQTtBQUNGO0FBQ0E7RUFGRTtJQUFBOUUsR0FBQTtJQUFBQyxLQUFBLEVBR0EsU0FBQWdGLEtBQUEsRUFBTztNQUNMLElBQUksSUFBSSxDQUFDQyxLQUFLLEVBQUU7UUFDZCxJQUFJLENBQUNBLEtBQUssQ0FBQ0QsSUFBSSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDQyxLQUFLLENBQUNJLE9BQU8sQ0FBQyxDQUFDO01BQ3RCO0lBQ0Y7O0lBRUE7QUFDRjtBQUNBO0VBRkU7SUFBQXRGLEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFtRixTQUFTckUsSUFBSSxFQUFFO01BQ2IsSUFBTXdFLFNBQVMsR0FBRyxJQUFJLENBQUNmLEtBQUssQ0FBQ3hJLE1BQU07TUFDbkMsSUFBSTRHLEtBQUs7TUFDVCxJQUFJNEMsSUFBSTtNQUNSLElBQUl2RixLQUFLO01BQ1QsSUFBSVgsTUFBTSxHQUFHLEVBQUU7O01BRWY7TUFDQSxJQUFJbUcsU0FBUyxHQUFHLElBQUksQ0FBQ2YsS0FBSyxHQUFHLEVBQUU7O01BRS9CO01BQ0EsS0FBS2MsSUFBSSxHQUFHLENBQUMsRUFBRUEsSUFBSSxHQUFHQyxTQUFTLEVBQUVELElBQUksSUFBSSxDQUFDLEVBQUU7UUFDMUM7UUFDQSxJQUFNckMsVUFBVSxHQUFHcEMsSUFBSSxHQUFJeUUsSUFBSSxHQUFHLElBQUksQ0FBQ2YsVUFBVSxHQUFJLElBQUksQ0FBQ0MsS0FBSzs7UUFFL0Q7UUFDQXpFLEtBQUssR0FBRyxDQUFDOztRQUVUO1FBQ0EsS0FBSzJDLEtBQUssR0FBRyxDQUFDLEVBQUVBLEtBQUssR0FBRzJDLFNBQVMsRUFBRTNDLEtBQUssSUFBSSxDQUFDLEVBQUU7VUFDN0MsSUFBTThDLElBQUksR0FBRyxJQUFJLENBQUNsQixLQUFLLENBQUM1QixLQUFLLENBQUM7VUFDOUIzQyxLQUFLLElBQUkrRCxXQUFXLENBQUMwQixJQUFJLENBQUNmLEtBQUssQ0FBQyxDQUFDeEIsVUFBVSxHQUFHdUMsSUFBSSxDQUFDZCxTQUFTLENBQUM7UUFDL0Q7O1FBRUE7UUFDQTNFLEtBQUssSUFBSXNGLFNBQVM7UUFFbEJqRyxNQUFNLENBQUNxRyxJQUFJLENBQUMsQ0FBQ3hDLFVBQVUsRUFBRWxELEtBQUssQ0FBQyxDQUFDO01BQ2xDO01BRUEsT0FBT1gsTUFBTTtJQUNmOztJQUVBO0FBQ0Y7QUFDQTtFQUZFO0lBQUFVLEdBQUE7SUFBQUMsS0FBQSxFQUdBLFNBQUFvRixLQUFLL0YsTUFBTSxFQUFFO01BQ1gsSUFBTXNHLFdBQVcsR0FBRyxJQUFJLENBQUNuRSxNQUFNLENBQUN6RixNQUFNO01BQ3RDLElBQUk2SSxhQUFhLEdBQUcsSUFBSSxDQUFDQSxhQUFhO01BQ3RDLElBQUlqQyxLQUFLO01BQ1QsSUFBSTRDLElBQUk7TUFDUixJQUFJSyxTQUFTLEdBQUcsQ0FBQztNQUNqQixJQUFNbEcsS0FBSyxHQUFHLEVBQUU7TUFFaEIsS0FBSzZGLElBQUksR0FBRyxDQUFDLEVBQUVBLElBQUksR0FBRyxJQUFJLENBQUNkLEtBQUssRUFBRWMsSUFBSSxJQUFJLENBQUMsRUFBRTtRQUMzQztRQUNBLElBQUFNLFlBQUEsR0FBQTVDLG9CQUFBLENBQXNCNUQsTUFBTSxDQUFDa0csSUFBSSxDQUFDO1VBQTNCekUsSUFBSSxHQUFBK0UsWUFBQTtVQUFFN0YsS0FBSyxHQUFBNkYsWUFBQTs7UUFFbEI7UUFDQSxLQUFLbEQsS0FBSyxHQUFHLENBQUMsRUFBRUEsS0FBSyxHQUFHZ0QsV0FBVyxFQUFFaEQsS0FBSyxJQUFJLENBQUMsRUFBRTtVQUMvQyxJQUFNZixLQUFLLEdBQUcsSUFBSSxDQUFDSixNQUFNLENBQUNtQixLQUFLLENBQUM7VUFDaEMsSUFDRTNDLEtBQUssR0FBRzRCLEtBQUssQ0FBQ0csS0FBSyxJQUNuQkgsS0FBSyxDQUFDRyxLQUFLLEdBQUc2QyxhQUFhLElBQzNCQSxhQUFhLEtBQUssSUFBSSxFQUN0QjtZQUNBO1lBQ0EsSUFBSSxDQUFDa0IsT0FBTyxDQUFDaEYsSUFBSSxFQUFFYyxLQUFLLENBQUNtRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkNyRyxLQUFLLENBQUNnRyxJQUFJLENBQUMsQ0FBQzVFLElBQUksRUFBRWMsS0FBSyxDQUFDRyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDckM2RCxTQUFTLElBQUksQ0FBQztVQUNoQixDQUFDLE1BQU0sSUFDTDVGLEtBQUssR0FBRzRCLEtBQUssQ0FBQ0csS0FBSyxJQUNuQkgsS0FBSyxDQUFDRyxLQUFLLEdBQUc2QyxhQUFhLElBQzNCQSxhQUFhLEtBQUssSUFBSSxFQUN0QjtZQUNBO1lBQ0EsSUFBSSxDQUFDa0IsT0FBTyxDQUFDaEYsSUFBSSxFQUFFYyxLQUFLLENBQUNtRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbkNyRyxLQUFLLENBQUNnRyxJQUFJLENBQUMsQ0FBQzVFLElBQUksRUFBRWMsS0FBSyxDQUFDRyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDdEM2RCxTQUFTLElBQUksQ0FBQztVQUNoQjtRQUNGOztRQUVBO1FBQ0FoQixhQUFhLEdBQUc1RSxLQUFLO01BQ3ZCOztNQUVBO01BQ0EsSUFBSSxDQUFDNEUsYUFBYSxHQUFHQSxhQUFhOztNQUVsQztNQUNBLE9BQU9sRixLQUFLO0lBQ2Q7O0lBRUE7QUFDRjtBQUNBO0VBRkU7SUFBQUssR0FBQTtJQUFBQyxLQUFBLEVBR0EsU0FBQThGLFFBQVFoRixJQUFJLEVBQUVrRixLQUFLLEVBQUU7TUFDbkI7TUFDQUEsS0FBSyxDQUFDQyxVQUFVLENBQUNiLElBQUksQ0FBQ3RFLElBQUksRUFBRWtGLEtBQUssQ0FBQztJQUNwQztFQUFDO0VBQUEsT0FBQTFCLE1BQUE7QUFBQTs7O0FDakswQjtBQUU3QixJQUFNNEIsVUFBVSxHQUFHLElBQUl2TCxxQkFBZSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM5QyxJQUFNeUwsSUFBSSxHQUFHLElBQUl6TCxTQUFTLENBQUMsR0FBRyxDQUFDO0FBQy9CdUwsVUFBVSxDQUFDSSxPQUFPLENBQUNGLElBQUksQ0FBQztBQUN4QkEsSUFBSSxDQUFDRyxhQUFhLENBQUMsQ0FBQztBQUVwQiw2Q0FBZUwsVUFBVSxFOzs7Ozs7Ozs7O0FDUEk7QUFDYztBQUNiO0FBRTlCLElBQU1PLFlBQVksR0FBRyxDQUFDO0FBQUMsSUFFRkMsZUFBTztFQUMxQixTQUFBQSxRQUFBL0gsSUFBQSxFQUFnQztJQUFBLElBQWxCZ0ksT0FBTyxHQUFBaEksSUFBQSxDQUFQZ0ksT0FBTztNQUFFQyxLQUFLLEdBQUFqSSxJQUFBLENBQUxpSSxLQUFLO0lBQUE5SCxzQkFBQSxPQUFBNEgsT0FBQTtJQUMxQixJQUFJLENBQUNFLEtBQUssR0FBR0EsS0FBSztJQUNsQixJQUFJLENBQUNELE9BQU8sR0FBR0EsT0FBTyxDQUFDRSxHQUFHLENBQUMsVUFBQUMsS0FBQSxFQUFtQjtNQUFBLElBQWJDLE1BQU0sR0FBQUMsUUFBQSxNQUFBQyx5QkFBQSxDQUFBSCxLQUFBLEdBQUFBLEtBQUE7TUFDckNDLE1BQU0sQ0FBQ0csT0FBTyxHQUFHLEVBQUU7TUFDbkJILE1BQU0sQ0FBQ3BFLEtBQUssR0FBRyxDQUFDLENBQUM7TUFDakIsS0FBSyxJQUFJd0UsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHVixZQUFZLEVBQUVVLENBQUMsRUFBRSxFQUFFO1FBQ3JDLElBQUl4SyxFQUFFLEdBQUdvSyxNQUFNLENBQUNwSyxFQUFFO1FBQ2xCLElBQUk0QyxNQUFNLENBQUM2SCxRQUFRLENBQUNDLElBQUksQ0FBQ3JNLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRTtVQUN6QzJCLEVBQUUsR0FBRyxvQkFBb0IsR0FBR0EsRUFBRTtRQUNoQztRQUNBLElBQUkySyxNQUFNLEdBQUcsSUFBSTNNLGFBQVcsQ0FBQztVQUMzQjZNLEdBQUcsRUFBRTdLLEVBQUU7VUFDUDhLLFNBQVMsRUFBRSxJQUFJO1VBQ2ZDLFlBQVksRUFBRTtRQUNoQixDQUFDLENBQUM7UUFDRkosTUFBTSxDQUFDaEIsT0FBTyxDQUFDRSxNQUFNLENBQUM7UUFDdEJPLE1BQU0sQ0FBQ0csT0FBTyxDQUFDeEIsSUFBSSxDQUFDNEIsTUFBTSxDQUFDO01BQzdCO01BQ0EsT0FBT1AsTUFBTTtJQUNmLENBQUMsQ0FBQztFQUNKO0VBQUNqSCxtQkFBQSxDQUFBNEcsT0FBQTtJQUFBM0csR0FBQTtJQUFBQyxLQUFBLEVBRUQsU0FBQW9GLEtBQUt0RSxJQUFJLEVBQUU2RyxPQUFPLEVBQUU7TUFDbEIsSUFBTTNCLEtBQUssR0FBRzJCLE9BQU8sQ0FBQ2hGLEtBQUssR0FDdkIsSUFBSSxDQUFDZ0UsT0FBTyxDQUFDZ0IsT0FBTyxDQUFDaEYsS0FBSyxDQUFDLEdBQzNCakgsTUFBTSxDQUFDLElBQUksQ0FBQ2lMLE9BQU8sQ0FBQztNQUV4QlgsS0FBSyxDQUFDckQsS0FBSyxHQUFHLENBQUNxRCxLQUFLLENBQUNyRCxLQUFLLEdBQUcsQ0FBQyxJQUFJOEQsWUFBWTtNQUU5QyxJQUFNYSxNQUFNLEdBQUd0QixLQUFLLENBQUNrQixPQUFPLENBQUNsQixLQUFLLENBQUNyRCxLQUFLLENBQUM7TUFFekMsSUFBSSxJQUFJLENBQUNpRSxLQUFLLEVBQUU7UUFDZFUsTUFBTSxDQUFDSSxZQUFZLEdBQ2pCLENBQUNDLE9BQU8sQ0FBQ2hELFNBQVMsR0FBR2pKLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHVyxjQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJMkosS0FBSyxDQUFDNEIsSUFBSTtNQUMxRTtNQUVBTixNQUFNLENBQUN6QyxLQUFLLENBQUMvRCxJQUFJLElBQUksQ0FBQyxDQUFDO0lBQ3pCO0VBQUM7RUFBQSxPQUFBNEYsT0FBQTtBQUFBOzs7QUM1QzZCO0FBRXpCLElBQU1tQixPQUFPLEdBQUcsSUFBSW5CLGVBQU8sQ0FBQztFQUNqQ0UsS0FBSyxFQUFFLElBQUk7RUFDWEQsT0FBTyxFQUFFLENBQ1A7SUFBRWlCLElBQUksRUFBRSxHQUFHO0lBQUVqTCxFQUFFLEVBQUU7RUFBb0QsQ0FBQyxFQUN0RTtJQUFFaUwsSUFBSSxFQUFFLEdBQUc7SUFBRWpMLEVBQUUsRUFBRTtFQUFvRCxDQUFDLEVBQ3RFO0lBQUVpTCxJQUFJLEVBQUUsR0FBRztJQUFFakwsRUFBRSxFQUFFO0VBQW9ELENBQUMsRUFDdEU7SUFBRWlMLElBQUksRUFBRSxHQUFHO0lBQUVqTCxFQUFFLEVBQUU7RUFBdUQsQ0FBQztBQUU3RSxDQUFDLENBQUM7QUFFSyxJQUFNbUwsS0FBSyxHQUFHLElBQUlwQixlQUFPLENBQUM7RUFDL0JFLEtBQUssRUFBRSxLQUFLO0VBQ1pELE9BQU8sRUFBRSxDQUNQO0lBQUVoSyxFQUFFLEVBQUU7RUFBcUIsQ0FBQyxFQUM1QjtJQUFFQSxFQUFFLEVBQUU7RUFBdUIsQ0FBQztFQUM5QjtFQUNBO0lBQUVBLEVBQUUsRUFBRTtFQUFzQixDQUFDLEVBQzdCO0lBQUVBLEVBQUUsRUFBRTtFQUFzQixDQUFDO0FBRWpDLENBQUMsQ0FBQyxDOztBQ3JCYSxTQUFTLGFBQU87QUFDL0I7O0FBRUEsU0FBUyxhQUFPO0FBQ2hCO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRyxFQUFFLGFBQU87QUFDWixDOztBQ1JrQztBQUNuQixTQUFTLHVCQUFZO0FBQ3BDLE1BQU0sYUFBTztBQUNiO0FBQ0E7QUFDQTtBQUNBLFFBQVEsYUFBTztBQUNmO0FBQ0E7QUFDQTtBQUNBLEM7O0FDVmtDO0FBQ1M7QUFDNUIsU0FBUywyQkFBYztBQUN0QyxZQUFZLHVCQUFXO0FBQ3ZCLFNBQVMsYUFBTztBQUNoQixDOztBQ0wrQztBQUNoQztBQUNmLFFBQVEsMkJBQWE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxDOztBQ2RlLFNBQVMsaUNBQWlCO0FBQ3pDO0FBQ0EseUNBQXlDLFNBQVM7QUFDbEQ7QUFDQSxDOztBQ0pxRDtBQUN0QztBQUNmLGlDQUFpQyxpQ0FBZ0I7QUFDakQsQzs7QUNIZTtBQUNmO0FBQ0EsQzs7QUNGcUQ7QUFDdEMsU0FBUyxxREFBMkI7QUFDbkQ7QUFDQSxvQ0FBb0MsaUNBQWdCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBLHNGQUFzRixpQ0FBZ0I7QUFDdEcsQzs7QUNSZTtBQUNmO0FBQ0EsQzs7QUNGdUQ7QUFDSjtBQUNzQjtBQUNsQjtBQUN4QztBQUNmLFNBQVMsa0JBQWlCLFNBQVMsZ0JBQWUsU0FBUyxxREFBMEIsU0FBUyxrQkFBaUI7QUFDL0csQzs7QUNOZSxTQUFTLDZCQUFlO0FBQ3ZDO0FBQ0EsQzs7QUNGZSxTQUFTLHlDQUFxQjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBWSw2RUFBNkU7QUFDakcsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7O0FDMUJlLFNBQVMsK0JBQWdCO0FBQ3hDO0FBQ0EsQzs7QUNGaUQ7QUFDWTtBQUNZO0FBQ3RCO0FBQ3BDLFNBQVMsMkJBQWM7QUFDdEMsU0FBUyw2QkFBYyxTQUFTLHlDQUFvQixZQUFZLHFEQUEwQixZQUFZLCtCQUFlO0FBQ3JILEM7Ozs7O0FDTkE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ087QUFDUDtBQUNBLE1BQU0sS0FBd0UsRUFBRSxxQkFPN0U7QUFDSDtBQUNPO0FBQ1A7QUFDQSxNQUFNLEtBQXdFLEVBQUUscUJBTzdFO0FBQ0g7QUFDTztBQUNQO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBZSxXQUFXLEVBQUM7QUFDM0IsbUI7O0FDcER3RDtBQUN4Qjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksVUFBTztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixjQUFjO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixhQUFPLG9CQUFvQixhQUFPO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBZSxPQUFPLEU7O0FDdERTO0FBQ2hCO0FBQ2YsY0FBYyxZQUFZO0FBQzFCO0FBQ0EsZUFBZSxpQkFBaUI7QUFDaEM7QUFDQSx3RUFBd0UsYUFBYTtBQUNyRjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDOztBQ1plO0FBQ2Y7QUFDQSxDOztBQ0YrQjtBQUNVOztBQUV6QztBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsS0FBK0IsSUFBSSxTQUFTLEtBQUsscUJBQXFCLEdBQUcsZUFBZTtBQUM5Ryw0REFBZSxlQUFlLEVBQUM7QUFDeEI7QUFDUCxzQkFBc0IsWUFBWTtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEU7O0FDdkJzRTtBQUN2QztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2U7QUFDZixtQkFBbUIsWUFBWTtBQUMvQix3QkFBd0IsY0FBYztBQUN0Qyx1QkFBdUIsMkJBQWM7QUFDckM7QUFDQTtBQUNBLEVBQUUsZUFBZTtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7O0FDMUJzRTtBQUNwQztBQUN3QjtBQUN4QjtBQUNsQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNlO0FBQ2YseUJBQXlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWtCLFlBQVE7QUFDMUI7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0EsS0FBSztBQUNMLGlCQUFpQiwyQkFBYztBQUMvQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG1CQUFtQixRQUFRO0FBQzNCLG1CQUFtQixZQUFRO0FBQzNCLGlCQUFpQiwyQkFBYztBQUMvQjtBQUNBO0FBQ0EsRUFBRSxxQkFBcUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EsRUFBRSxxQkFBcUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBLHNCQUFzQixRQUFRO0FBQzlCO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDOztBQzlEZSxTQUFTLGVBQVE7QUFDaEMsRUFBRSxlQUFRO0FBQ1Ysb0JBQW9CLHNCQUFzQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGVBQVE7QUFDakIsQzs7QUNiZTtBQUNmO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyx1QkFBdUI7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7O0FDWDZFO0FBQzlELFNBQVMsK0NBQXdCO0FBQ2hEO0FBQ0EsZUFBZSw2QkFBNEI7QUFDM0M7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDZCQUE2QjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEM7O0FDZmlEO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDZTtBQUNmLGtCQUFrQixzQkFBc0I7QUFDeEM7QUFDQTtBQUNBLE1BQU0sZUFBYztBQUNwQixLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEM7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQSxXQUFXLFVBQVU7QUFDckIsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG1CQUFtQjtBQUNsQyxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLG1CQUFtQjtBQUNsQyxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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LGtCQUFrQjtBQUNuRHhDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDNlAsVUFBVSxDQUFDak8sS0FBSyxDQUFDNk4sTUFBTSxHQUFHLENBQUM7QUFDekMxUCxRQUFRLENBQUNDLElBQUksQ0FBQzZQLFVBQVUsQ0FBQ2pPLEtBQUssQ0FBQ1MsT0FBTyxHQUFHLENBQUM7QUFDMUN0QyxRQUFRLENBQUNDLElBQUksQ0FBQzZQLFVBQVUsQ0FBQ2pPLEtBQUssQ0FBQ0ksTUFBTSxHQUFHLE1BQU07QUFDOUNqQyxRQUFRLENBQUNDLElBQUksQ0FBQzZQLFVBQVUsQ0FBQ2pPLEtBQUssQ0FBQ0csS0FBSyxHQUFHLE1BQU07QUFFN0NYLG1CQUFtQixDQUFDLFlBQU07RUFDeEIsSUFBTUUsU0FBUyxHQUFHdkIsUUFBUSxDQUFDd0IsYUFBYSxDQUFDLEtBQUssQ0FBQztFQUMvQ0QsU0FBUyxDQUFDTSxLQUFLLENBQUNJLE1BQU0sR0FBRyxNQUFNO0VBQy9CVixTQUFTLENBQUNNLEtBQUssQ0FBQ0csS0FBSyxHQUFHLE1BQU07RUFDOUJoQyxRQUFRLENBQUNDLElBQUksQ0FBQ3lCLFNBQVMsR0FBRyxFQUFFO0VBQzVCMUIsUUFBUSxDQUFDQyxJQUFJLENBQUM2QyxXQUFXLENBQUN2QixTQUFTLENBQUM7RUFDcEMsSUFBTWdMLElBQUksR0FBR3NELDRCQUFVLENBQUN0TyxTQUFTLENBQUM7RUFDbENnTCxJQUFJLENBQUN3RCxNQUFNLGVBQUNyRCxtQkFBQSxDQUFDeUMsR0FBRyxNQUFFLENBQUMsQ0FBQztBQUN0QixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vdmVyc2lvbi5qcz8zMzgzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Fib3J0LWVycm9yLmpzPzczODIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/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/ZjlhMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mLmpzP2Y4ZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvUHJpbWl0aXZlLmpzPzk3NmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvUHJvcGVydHlLZXkuanM/YTJmYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHkuanM/ZDcxYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlMaWtlVG9BcnJheS5qcz8yMjJlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hcnJheVdpdGhvdXRIb2xlcy5qcz9jNDdkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pdGVyYWJsZVRvQXJyYXkuanM/ZDFiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanM/NmMyMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vbm9uSXRlcmFibGVTcHJlYWQuanM/MGFkOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXkuanM/ZjdhMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRoSG9sZXMuanM/MmJlNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaXRlcmFibGVUb0FycmF5TGltaXQuanM/ODJkZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vbm9uSXRlcmFibGVSZXN0LmpzPzRlYmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXkuanM/ZmNkMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy93YXJuaW5nLmpzPzJiMDYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaXNFcXVhbC5qcz81OWZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZUV2ZW50LmpzPzk4MTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvRG9tL2NhblVzZURvbS5qcz8zMGQ5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZUxheW91dEVmZmVjdC5qcz80Y2RhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZVN0YXRlLmpzPzc2NmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlTWVyZ2VkU3RhdGUuanM/ZTljMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kcy5qcz8zMzE3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlLmpzP2QyMTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzLmpzPzk0MjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDIuanM/YmI3NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9LZXlDb2RlLmpzP2UwODkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9jb250ZXh0LmpzPzkzZDciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy91dGlsLmpzPzllZjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9IYW5kbGVzL0hhbmRsZS5qcz85OWRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvSGFuZGxlcy9pbmRleC5qcz9iMDE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvaG9va3MvdXNlRHJhZy5qcz8xZjNlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvVHJhY2tzL1RyYWNrLmpzPzM0ODQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9UcmFja3MvaW5kZXguanM/YmZlOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL01hcmtzL01hcmsuanM/YzRiMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL01hcmtzL2luZGV4LmpzPzhjNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9TdGVwcy9Eb3QuanM/NDU0MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL1N0ZXBzL2luZGV4LmpzP2M4NTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9ob29rcy91c2VPZmZzZXQuanM/ZDJlNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL1NsaWRlci5qcz8zYjNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvaW5kZXguanM/YjIyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9hc3NldHMvYm9vdHN0cmFwLmNzcz8wYzg4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZU1lbW8uanM/NjJiYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9yZWYuanM/NzNlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvQ29udGV4dC5qcz9kODEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy91c2VEb20uanM/ZjhiOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9Eb20vY29udGFpbnMuanM/OTc4NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9Eb20vZHluYW1pY0NTUy5qcz8wNTRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2dldFNjcm9sbEJhclNpemUuanM/YWIxZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvdXRpbC5qcz85NDliIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy91c2VTY3JvbGxMb2NrZXIuanM/YTg3MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvbW9jay5qcz80OTYwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3BvcnRhbC9lcy9Qb3J0YWwuanM/NTVjOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvaW5kZXguanM/NmQzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9DaGlsZHJlbi90b0FycmF5LmpzPzY2NmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvRG9tL2ZpbmRET01Ob2RlLmpzPzliZTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3Jlc2l6ZS1vYnNlcnZlci1wb2x5ZmlsbC9kaXN0L1Jlc2l6ZU9ic2VydmVyLmVzLmpzPzZkZDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXJlc2l6ZS1vYnNlcnZlci9lcy91dGlscy9vYnNlcnZlclV0aWwuanM/NDcxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2suanM/Njk1NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3MuanM/OTI5NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2V0UHJvdG90eXBlT2YuanM/NDM1MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHMuanM/OThhMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZ2V0UHJvdG90eXBlT2YuanM/MzE2NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0LmpzP2RkY2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZC5qcz80MmNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuLmpzPzBkNDciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZVN1cGVyLmpzPzNkOTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXJlc2l6ZS1vYnNlcnZlci9lcy9TaW5nbGVPYnNlcnZlci9Eb21XcmFwcGVyLmpzPzgxNzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXJlc2l6ZS1vYnNlcnZlci9lcy9Db2xsZWN0aW9uLmpzP2NmM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXJlc2l6ZS1vYnNlcnZlci9lcy9TaW5nbGVPYnNlcnZlci9pbmRleC5qcz81MmU3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1yZXNpemUtb2JzZXJ2ZXIvZXMvaW5kZXguanM/Yjc2ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VJZC5qcz81NzYxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2lzTW9iaWxlLmpzP2U1OWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9jb250ZXh0LmpzP2M1NTMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9ob29rcy91c2VBY3Rpb24uanM/YTA2OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9Eb20vaXNWaXNpYmxlLmpzP2M3ZmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy91dGlsLmpzPzEyMzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9ob29rcy91c2VBbGlnbi5qcz85NDRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvaG9va3MvdXNlV2F0Y2guanM/YTMwZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2NvbnRleHQuanM/ODhhNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL0RvbVdyYXBwZXIuanM/OGJmYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2ludGVyZmFjZS5qcz80ZDIwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvdXRpbC9tb3Rpb24uanM/OGZhMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2hvb2tzL3VzZURvbU1vdGlvbkV2ZW50cy5qcz9lZmUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaG9va3MvdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdC5qcz9mYmRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL3JhZi5qcz9jMjAyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaG9va3MvdXNlTmV4dEZyYW1lLmpzPzA5MTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9ob29rcy91c2VTdGVwUXVldWUuanM/MTU1YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2hvb2tzL3VzZVN0YXR1cy5qcz9lZWFjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvQ1NTTW90aW9uLmpzPzdiMjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy91dGlsL2RpZmYuanM/NGIzNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL0NTU01vdGlvbkxpc3QuanM/OWNhNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2luZGV4LmpzP2YxNzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9Qb3B1cC9BcnJvdy5qcz83YzNmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvUG9wdXAvTWFzay5qcz8xMDUwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvUG9wdXAvUG9wdXBDb250ZW50LmpzPzUwYWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9Qb3B1cC9pbmRleC5qcz84MGMwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvVHJpZ2dlcldyYXBwZXIuanM/NjQwZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL2luZGV4LmpzP2JmNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvZXMvcGxhY2VtZW50cy5qcz9lZTJjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy10b29sdGlwL2VzL1BvcHVwLmpzPzVjMDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvZXMvVG9vbHRpcC5qcz9jN2Q5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy10b29sdGlwL2VzL2luZGV4LmpzPzM4YjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3VpL1Rvb2x0aXBTbGlkZXIudHN4PzJhZDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9hc3NldHMvaW5kZXguY3NzP2ZkMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3VpL0NvbnRyb2xzLmpzeD9lOTEzIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy91aS9BcHAuanN4PzQ0MmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2luZGV4LmpzeD9lZDEyIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCB2ZXJzaW9uID0gXCIxNC43Ljc3XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD12ZXJzaW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBYm9ydEVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0Fib3J0RXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFib3J0LWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChpbnNlcnRFbGVtZW50SW5TZXQpID0+IHtcbiAgICByZXR1cm4gKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGFjdGl2ZUlucHV0c1tpbnB1dF0sIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyA9IChhdWRpb05vZGVDb25uZWN0aW9uc1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGF1ZGlvTm9kZVJlbmRlcmVyLCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0cy5wdXNoKG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNTdG9yZS5zZXQoYXVkaW9Ob2RlLCB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dHMsXG4gICAgICAgICAgICBvdXRwdXRzOiBuZXcgU2V0KCksXG4gICAgICAgICAgICBwYXNzaXZlSW5wdXRzOiBuZXcgV2Vha01hcCgpLFxuICAgICAgICAgICAgcmVuZGVyZXI6IGF1ZGlvTm9kZVJlbmRlcmVyXG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IChhdWRpb1BhcmFtQ29ubmVjdGlvbnNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9QYXJhbSwgYXVkaW9QYXJhbVJlbmRlcmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvUGFyYW1Db25uZWN0aW9uc1N0b3JlLnNldChhdWRpb1BhcmFtLCB7IGFjdGl2ZUlucHV0czogbmV3IFNldCgpLCBwYXNzaXZlSW5wdXRzOiBuZXcgV2Vha01hcCgpLCByZW5kZXJlcjogYXVkaW9QYXJhbVJlbmRlcmVyIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSA9IG5ldyBXZWFrU2V0KCk7XG5leHBvcnQgY29uc3QgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fTk9ERV9TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEFVRElPX1BBUkFNX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBDT05URVhUX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBFVkVOVF9MSVNURU5FUlMgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IENZQ0xFX0NPVU5URVJTID0gbmV3IFdlYWtNYXAoKTtcbi8vIFRoaXMgY2x1bmt5IG5hbWUgaXMgYm9ycm93ZWQgZnJvbSB0aGUgc3BlYy4gOi0pXG5leHBvcnQgY29uc3QgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBOT0RFX1RPX1BST0NFU1NPUl9NQVBTID0gbmV3IFdlYWtNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdsb2JhbHMuanMubWFwIiwiY29uc3QgaGFuZGxlciA9IHtcbiAgICBjb25zdHJ1Y3QoKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVyO1xuICAgIH1cbn07XG5leHBvcnQgY29uc3QgaXNDb25zdHJ1Y3RpYmxlID0gKGNvbnN0cnVjdGlibGUpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBwcm94eSA9IG5ldyBQcm94eShjb25zdHJ1Y3RpYmxlLCBoYW5kbGVyKTtcbiAgICAgICAgbmV3IHByb3h5KCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tdW51c2VkLWV4cHJlc3Npb25cbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWNvbnN0cnVjdGlibGUuanMubWFwIiwiLypcbiAqIFRoaXMgbWFzc2l2ZSByZWdleCB0cmllcyB0byBjb3ZlciBhbGwgdGhlIGZvbGxvd2luZyBjYXNlcy5cbiAqXG4gKiBpbXBvcnQgJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IHsgbmFtZWRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IHsgbmFtZWRJbXBvcnQgYXMgcmVuYW1lbmRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0ICogYXMgbmFtZXNwYWNlSW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgeyBuYW1lZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgeyBuYW1lZEltcG9ydCBhcyByZW5hbWVuZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgKiBhcyBuYW1lc3BhY2VJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqL1xuY29uc3QgSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCA9IC9eaW1wb3J0KD86KD86W1xcc10rW1xcd10rfCg/OltcXHNdK1tcXHddK1tcXHNdKiwpP1tcXHNdKlxce1tcXHNdKltcXHddKyg/OltcXHNdK2FzW1xcc10rW1xcd10rKT8oPzpbXFxzXSosW1xcc10qW1xcd10rKD86W1xcc10rYXNbXFxzXStbXFx3XSspPykqW1xcc10qfXwoPzpbXFxzXStbXFx3XStbXFxzXSosKT9bXFxzXSpcXCpbXFxzXSthc1tcXHNdK1tcXHddKylbXFxzXStmcm9tKT8oPzpbXFxzXSopKFwiKFteXCJcXFxcXXxcXFxcLikrXCJ8JyhbXidcXFxcXXxcXFxcLikrJykoPzpbXFxzXSopOz8vOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm1heC1saW5lLWxlbmd0aFxuZXhwb3J0IGNvbnN0IHNwbGl0SW1wb3J0U3RhdGVtZW50cyA9IChzb3VyY2UsIHVybCkgPT4ge1xuICAgIGNvbnN0IGltcG9ydFN0YXRlbWVudHMgPSBbXTtcbiAgICBsZXQgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgPSBzb3VyY2UucmVwbGFjZSgvXltcXHNdKy8sICcnKTtcbiAgICBsZXQgcmVzdWx0ID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMubWF0Y2goSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCk7XG4gICAgd2hpbGUgKHJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCB1bnJlc29sdmVkVXJsID0gcmVzdWx0WzFdLnNsaWNlKDEsIC0xKTtcbiAgICAgICAgY29uc3QgaW1wb3J0U3RhdGVtZW50V2l0aFJlc29sdmVkVXJsID0gcmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZSgvKFtcXHNdKyk/Oz8kLywgJycpXG4gICAgICAgICAgICAucmVwbGFjZSh1bnJlc29sdmVkVXJsLCBuZXcgVVJMKHVucmVzb2x2ZWRVcmwsIHVybCkudG9TdHJpbmcoKSk7XG4gICAgICAgIGltcG9ydFN0YXRlbWVudHMucHVzaChpbXBvcnRTdGF0ZW1lbnRXaXRoUmVzb2x2ZWRVcmwpO1xuICAgICAgICBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyA9IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzLnNsaWNlKHJlc3VsdFswXS5sZW5ndGgpLnJlcGxhY2UoL15bXFxzXSsvLCAnJyk7XG4gICAgICAgIHJlc3VsdCA9IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzLm1hdGNoKElNUE9SVF9TVEFURU1FTlRfUkVHRVgpO1xuICAgIH1cbiAgICByZXR1cm4gW2ltcG9ydFN0YXRlbWVudHMuam9pbignOycpLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c107XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3BsaXQtaW1wb3J0LXN0YXRlbWVudHMuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBpc0NvbnN0cnVjdGlibGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWNvbnN0cnVjdGlibGUnO1xuaW1wb3J0IHsgc3BsaXRJbXBvcnRTdGF0ZW1lbnRzIH0gZnJvbSAnLi4vaGVscGVycy9zcGxpdC1pbXBvcnQtc3RhdGVtZW50cyc7XG5jb25zdCB2ZXJpZnlQYXJhbWV0ZXJEZXNjcmlwdG9ycyA9IChwYXJhbWV0ZXJEZXNjcmlwdG9ycykgPT4ge1xuICAgIGlmIChwYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkICYmICFBcnJheS5pc0FycmF5KHBhcmFtZXRlckRlc2NyaXB0b3JzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgcGFyYW1ldGVyRGVzY3JpcHRvcnMgcHJvcGVydHkgb2YgZ2l2ZW4gdmFsdWUgZm9yIHByb2Nlc3NvckN0b3IgaXMgbm90IGFuIGFycmF5LicpO1xuICAgIH1cbn07XG5jb25zdCB2ZXJpZnlQcm9jZXNzb3JDdG9yID0gKHByb2Nlc3NvckN0b3IpID0+IHtcbiAgICBpZiAoIWlzQ29uc3RydWN0aWJsZShwcm9jZXNzb3JDdG9yKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgZ2l2ZW4gdmFsdWUgZm9yIHByb2Nlc3NvckN0b3Igc2hvdWxkIGJlIGEgY29uc3RydWN0b3IuJyk7XG4gICAgfVxuICAgIGlmIChwcm9jZXNzb3JDdG9yLnByb3RvdHlwZSA9PT0gbnVsbCB8fCB0eXBlb2YgcHJvY2Vzc29yQ3Rvci5wcm90b3R5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBzaG91bGQgaGF2ZSBhIHByb3RvdHlwZS4nKTtcbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvV29ya2xldE1vZHVsZSA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBldmFsdWF0ZVNvdXJjZSwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGZldGNoU291cmNlLCBnZXROYXRpdmVDb250ZXh0LCBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBvbmdvaW5nUmVxdWVzdHMsIHJlc29sdmVkUmVxdWVzdHMsIHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQsIHdpbmRvdykgPT4ge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgcmV0dXJuIChjb250ZXh0LCBtb2R1bGVVUkwsIG9wdGlvbnMgPSB7IGNyZWRlbnRpYWxzOiAnb21pdCcgfSkgPT4ge1xuICAgICAgICBjb25zdCByZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ID0gcmVzb2x2ZWRSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgIGlmIChyZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgcmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dC5oYXMobW9kdWxlVVJMKSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9IG9uZ29pbmdSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgIGlmIChvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZU9mT25nb2luZ1JlcXVlc3QgPSBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuZ2V0KG1vZHVsZVVSTCk7XG4gICAgICAgICAgICBpZiAocHJvbWlzZU9mT25nb2luZ1JlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgLy8gQnVnICM1OTogU2FmYXJpIGRvZXMgbm90IGltcGxlbWVudCB0aGUgYXVkaW9Xb3JrbGV0IHByb3BlcnR5LlxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmF0aXZlQ29udGV4dC5hdWRpb1dvcmtsZXQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBmZXRjaFNvdXJjZShtb2R1bGVVUkwpXG4gICAgICAgICAgICAgICAgLnRoZW4oKFtzb3VyY2UsIGFic29sdXRlVXJsXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtpbXBvcnRTdGF0ZW1lbnRzLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c10gPSBzcGxpdEltcG9ydFN0YXRlbWVudHMoc291cmNlLCBhYnNvbHV0ZVVybCk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdzpcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogJHsgaW1wb3J0U3RhdGVtZW50cyB9O1xuICAgICAgICAgICAgICAgICAqICgoYSwgYikgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAoYVtiXSA9IGFbYl0gfHwgWyBdKS5wdXNoKFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgKEF1ZGlvV29ya2xldFByb2Nlc3NvciwgZ2xvYmFsLCByZWdpc3RlclByb2Nlc3Nvciwgc2FtcGxlUmF0ZSwgc2VsZiwgd2luZG93KSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgJHsgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgfVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAqICAgICApO1xuICAgICAgICAgICAgICAgICAqIH0pKHdpbmRvdywgJ19BV0dTJyk7XG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRTb3VyY2UgPSBgJHtpbXBvcnRTdGF0ZW1lbnRzfTsoKGEsYik9PnsoYVtiXT1hW2JdfHxbXSkucHVzaCgoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLGdsb2JhbCxyZWdpc3RlclByb2Nlc3NvcixzYW1wbGVSYXRlLHNlbGYsd2luZG93KT0+eyR7c291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHN9XG59KX0pKHdpbmRvdywnX0FXR1MnKWA7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRXZhbHVhdGluZyB0aGUgZ2l2ZW4gc291cmNlIGNvZGUgaXMgYSBwb3NzaWJsZSBzZWN1cml0eSBwcm9ibGVtLlxuICAgICAgICAgICAgICAgIHJldHVybiBldmFsdWF0ZVNvdXJjZSh3cmFwcGVkU291cmNlKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgPSB3aW5kb3cuX0FXR1MucG9wKCk7XG4gICAgICAgICAgICAgICAgaWYgKGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBldmFsdWF0ZUF1ZGlvV29ya2xldEdsb2JhbFNjb3BlKGNsYXNzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG4gICAgICAgICAgICAgICAgfSwgdW5kZWZpbmVkLCAobmFtZSwgcHJvY2Vzc29yQ3RvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS50cmltKCkgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcC5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UHJvY2Vzc29yQ3Rvcihwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzKHByb2Nlc3NvckN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLnNldChuYW1lLCBwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVByb2Nlc3NvckN0b3IocHJvY2Vzc29yQ3Rvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQYXJhbWV0ZXJEZXNjcmlwdG9ycyhwcm9jZXNzb3JDdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUy5zZXQobmF0aXZlQ29udGV4dCwgbmV3IE1hcChbW25hbWUsIHByb2Nlc3NvckN0b3JdXSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCkpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIDogUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIGZldGNoU291cmNlKG1vZHVsZVVSTCksXG4gICAgICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKGNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0LCB0ZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0KSlcbiAgICAgICAgICAgIF0pLnRoZW4oKFtbc291cmNlLCBhYnNvbHV0ZVVybF0sIGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGN1cnJlbnRJbmRleDtcbiAgICAgICAgICAgICAgICBjb25zdCBbaW1wb3J0U3RhdGVtZW50cywgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHNdID0gc3BsaXRJbXBvcnRTdGF0ZW1lbnRzKHNvdXJjZSwgYWJzb2x1dGVVcmwpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNzk6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdG8gdHJhbnNmZXIgYW55IGJ1ZmZlciB3aGljaCBoYXMgYmVlbiBwYXNzZWQgdG8gdGhlIHByb2Nlc3MoKSBtZXRob2QgYXMgYW4gYXJndW1lbnQuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdy5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgIF9fYnVmZmVycyA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlID0gKChwb3N0TWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHJldHVybiAobWVzc2FnZSwgdHJhbnNmZXJhYmxlcykgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZFRyYW5zZmVyYWJsZXMgPSAodHJhbnNmZXJhYmxlcylcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgID8gdHJhbnNmZXJhYmxlcy5maWx0ZXIoKHRyYW5zZmVyYWJsZSkgPT4gIXRoaXMuX19idWZmZXJzLmhhcyh0cmFuc2ZlcmFibGUpKVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgOiB0cmFuc2ZlcmFibGVzO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIHJldHVybiBwb3N0TWVzc2FnZS5jYWxsKHRoaXMucG9ydCwgbWVzc2FnZSwgZmlsdGVyZWRUcmFuc2ZlcmFibGVzKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH0pKHRoaXMucG9ydC5wb3N0TWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICogICAgIH1cbiAgICAgICAgICAgICAgICAgKiB9XG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgID8gJ0F1ZGlvV29ya2xldFByb2Nlc3NvcidcbiAgICAgICAgICAgICAgICAgICAgOiAnY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige19fYj1uZXcgV2Vha1NldCgpO2NvbnN0cnVjdG9yKCl7c3VwZXIoKTsocD0+cC5wb3N0TWVzc2FnZT0ocT0+KG0sdCk9PnEuY2FsbChwLG0sdD90LmZpbHRlcih1PT4hdGhpcy5fX2IuaGFzKHUpKTp0KSkocC5wb3N0TWVzc2FnZSkpKHRoaXMucG9ydCl9fSc7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3MDogQ2hyb21lIGFuZCBFZGdlIGRvIGNhbGwgcHJvY2VzcygpIHdpdGggYW4gYXJyYXkgd2l0aCBlbXB0eSBjaGFubmVsRGF0YSBmb3IgZWFjaCBpbnB1dCBpZiBubyBpbnB1dCBpcyBjb25uZWN0ZWQuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTkwOiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBlcnJvciB3aGVuIGxvYWRpbmcgYW4gdW5wYXJzYWJsZSBtb2R1bGUuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdzpcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogYCR7IGltcG9ydFN0YXRlbWVudHMgfTtcbiAgICAgICAgICAgICAgICAgKiAoKEF1ZGlvV29ya2xldFByb2Nlc3NvciwgcmVnaXN0ZXJQcm9jZXNzb3IpID0+IHskeyBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyB9XG4gICAgICAgICAgICAgICAgICogfSkoXG4gICAgICAgICAgICAgICAgICogICAgICR7wqBwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0sXG4gICAgICAgICAgICAgICAgICogICAgIChuYW1lLCBwcm9jZXNzb3JDdG9yKSA9PiByZWdpc3RlclByb2Nlc3NvcihuYW1lLCBjbGFzcyBleHRlbmRzIHByb2Nlc3NvckN0b3Ige1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICBfX2NvbGxlY3RCdWZmZXJzID0gKGFycmF5KSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgYXJyYXkuZm9yRWFjaCgoZWxlbWVudCkgPT4gdGhpcy5fX2J1ZmZlcnMuYWRkKGVsZW1lbnQuYnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICBwcm9jZXNzIChpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBpbnB1dHMuZm9yRWFjaCh0aGlzLl9fY29sbGVjdEJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIG91dHB1dHMuZm9yRWFjaCh0aGlzLl9fY29sbGVjdEJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHRoaXMuX19jb2xsZWN0QnVmZmVycyhPYmplY3QudmFsdWVzKHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHJldHVybiBzdXBlci5wcm9jZXNzKFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAoaW5wdXRzLm1hcCgoaW5wdXQpID0+IGlucHV0LnNvbWUoKGNoYW5uZWxEYXRhKSA9PiBjaGFubmVsRGF0YS5sZW5ndGggPT09IDApKSA/IFsgXSA6IGlucHV0KSxcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgb3V0cHV0cyxcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgcGFyYW1ldGVyc1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgfSlcbiAgICAgICAgICAgICAgICAgKiApO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogcmVnaXN0ZXJQcm9jZXNzb3IoYF9fc2FjJHtjdXJyZW50SW5kZXh9YCwgY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgcHJvY2VzcyAoKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICogICAgIH1cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIH0pYFxuICAgICAgICAgICAgICAgICAqIGBgYFxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlckRlZmluaXRpb24gPSBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZSA/ICcnIDogJ19fYyA9IChhKSA9PiBhLmZvckVhY2goZT0+dGhpcy5fX2IuYWRkKGUuYnVmZmVyKSk7JztcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJSZWdpc3RyYXRpb24gPSBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICAgICAgICAgIDogJ2kuZm9yRWFjaCh0aGlzLl9fYyk7by5mb3JFYWNoKHRoaXMuX19jKTt0aGlzLl9fYyhPYmplY3QudmFsdWVzKHApKTsnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRTb3VyY2UgPSBgJHtpbXBvcnRTdGF0ZW1lbnRzfTsoKEF1ZGlvV29ya2xldFByb2Nlc3NvcixyZWdpc3RlclByb2Nlc3Nvcik9Pnske3NvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzfVxufSkoJHtwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yfSwobixwKT0+cmVnaXN0ZXJQcm9jZXNzb3IobixjbGFzcyBleHRlbmRzIHB7JHttZW1iZXJEZWZpbml0aW9ufXByb2Nlc3MoaSxvLHApeyR7YnVmZmVyUmVnaXN0cmF0aW9ufXJldHVybiBzdXBlci5wcm9jZXNzKGkubWFwKGo9Pmouc29tZShrPT5rLmxlbmd0aD09PTApP1tdOmopLG8scCl9fSkpO3JlZ2lzdGVyUHJvY2Vzc29yKCdfX3NhYyR7Y3VycmVudEluZGV4fScsY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7cHJvY2Vzcygpe3JldHVybiAhMX19KWA7XG4gICAgICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFt3cmFwcGVkU291cmNlXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCcgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5hdWRpb1dvcmtsZXRcbiAgICAgICAgICAgICAgICAgICAgLmFkZE1vZHVsZSh1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWxsb3cgdG8gY3JlYXRlIGFuIEF1ZGlvV29ya2xldE5vZGUgb24gYSBjbG9zZWQgQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCwgb3B0aW9ucykudGhlbigoKSA9PiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigobmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxOTA6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIHdoZW4gbG9hZGluZyBhbiB1bnBhcnNhYmxlIG1vZHVsZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgYF9fc2FjJHtjdXJyZW50SW5kZXh9YCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tdW51c2VkLWV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IFVSTC5yZXZva2VPYmplY3RVUkwodXJsKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvbmdvaW5nUmVxdWVzdHMuc2V0KGNvbnRleHQsIG5ldyBNYXAoW1ttb2R1bGVVUkwsIHByb21pc2VdXSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LnNldChtb2R1bGVVUkwsIHByb21pc2UpO1xuICAgICAgICB9XG4gICAgICAgIHByb21pc2VcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRSZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ID0gcmVzb2x2ZWRSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkUmVxdWVzdHMuc2V0KGNvbnRleHQsIG5ldyBTZXQoW21vZHVsZVVSTF0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZWRSZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0LmFkZChtb2R1bGVVUkwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9IG9uZ29pbmdSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5kZWxldGUobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLXdvcmtsZXQtbW9kdWxlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBnZXRWYWx1ZUZvcktleSA9IChtYXAsIGtleSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gbWFwLmdldChrZXkpO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQSB2YWx1ZSB3aXRoIHRoZSBnaXZlbiBrZXkgY291bGQgbm90IGJlIGZvdW5kLicpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXZhbHVlLWZvci1rZXkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHBpY2tFbGVtZW50RnJvbVNldCA9IChzZXQsIHByZWRpY2F0ZSkgPT4ge1xuICAgIGNvbnN0IG1hdGNoaW5nRWxlbWVudHMgPSBBcnJheS5mcm9tKHNldCkuZmlsdGVyKHByZWRpY2F0ZSk7XG4gICAgaWYgKG1hdGNoaW5nRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBFcnJvcignTW9yZSB0aGFuIG9uZSBlbGVtZW50IHdhcyBmb3VuZC4nKTtcbiAgICB9XG4gICAgaWYgKG1hdGNoaW5nRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdObyBlbGVtZW50IHdhcyBmb3VuZC4nKTtcbiAgICB9XG4gICAgY29uc3QgW21hdGNoaW5nRWxlbWVudF0gPSBtYXRjaGluZ0VsZW1lbnRzO1xuICAgIHNldC5kZWxldGUobWF0Y2hpbmdFbGVtZW50KTtcbiAgICByZXR1cm4gbWF0Y2hpbmdFbGVtZW50O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBpY2stZWxlbWVudC1mcm9tLXNldC5qcy5tYXAiLCJpbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IGdldFZhbHVlRm9yS2V5KHBhc3NpdmVJbnB1dHMsIHNvdXJjZSk7XG4gICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9uID0gcGlja0VsZW1lbnRGcm9tU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0ICYmIHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IGlucHV0KTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLmRlbGV0ZShzb3VyY2UpO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9uO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBFVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoRVZFTlRfTElTVEVORVJTLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgaWYgKEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIEF1ZGlvTm9kZSBpcyBhbHJlYWR5IHN0b3JlZC4nKTtcbiAgICB9XG4gICAgQUNUSVZFX0FVRElPX05PREVfU1RPUkUuYWRkKGF1ZGlvTm9kZSk7XG4gICAgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShhdWRpb05vZGUpLmZvckVhY2goKGV2ZW50TGlzdGVuZXIpID0+IGV2ZW50TGlzdGVuZXIodHJ1ZSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9Xb3JrbGV0Tm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BvcnQnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3Qgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICBpZiAoIUFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIEF1ZGlvTm9kZSBpcyBub3Qgc3RvcmVkLicpO1xuICAgIH1cbiAgICBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5kZWxldGUoYXVkaW9Ob2RlKTtcbiAgICBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSkuZm9yRWFjaCgoZXZlbnRMaXN0ZW5lcikgPT4gZXZlbnRMaXN0ZW5lcihmYWxzZSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4vc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuLy8gU2V0IHRoZSBpbnRlcm5hbFN0YXRlIG9mIHRoZSBhdWRpb05vZGUgdG8gJ3Bhc3NpdmUnIGlmIGl0IGlzIG5vdCBhbiBBdWRpb1dvcmtsZXROb2RlIGFuZCBpZiBpdCBoYXMgbm8gJ2FjdGl2ZScgaW5wdXQgY29ubmVjdGlvbnMuXG5leHBvcnQgY29uc3Qgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgPSAoYXVkaW9Ob2RlLCBhY3RpdmVJbnB1dHMpID0+IHtcbiAgICBpZiAoIWlzQXVkaW9Xb3JrbGV0Tm9kZShhdWRpb05vZGUpICYmIGFjdGl2ZUlucHV0cy5ldmVyeSgoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zLnNpemUgPT09IDApKSB7XG4gICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUoYXVkaW9Ob2RlKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUtd2hlbi1uZWNlc3NhcnkuanMubWFwIiwiaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5IH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeSc7XG5leHBvcnQgY29uc3QgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUsIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgaW5zZXJ0RWxlbWVudEluU2V0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNQYXJ0T2ZBQ3ljbGUsIGlzUGFzc2l2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIGNvbnN0IHRhaWxUaW1lVGltZW91dElkcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0LCBpc09mZmxpbmUpID0+IHtcbiAgICAgICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgICAgICBjb25zdCBldmVudExpc3RlbmVycyA9IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgY29uc3QgZXZlbnRMaXN0ZW5lciA9IChpc0FjdGl2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlU291cmNlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGlzUGFzc2l2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGFzc2l2ZUlucHV0cywgaW5wdXQsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRhaWxUaW1lID0gZ2V0QXVkaW9Ob2RlVGFpbFRpbWUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIGlmICh0YWlsVGltZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFpbFRpbWVUaW1lb3V0SWQgPSB0YWlsVGltZVRpbWVvdXRJZHMuZ2V0KGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhaWxUaW1lVGltZW91dElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0YWlsVGltZVRpbWVvdXRJZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGFpbFRpbWVUaW1lb3V0SWRzLnNldChkZXN0aW5hdGlvbiwgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkoZGVzdGluYXRpb24sIGFjdGl2ZUlucHV0cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIHRhaWxUaW1lICogMTAwMCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluc2VydEVsZW1lbnRJblNldChvdXRwdXRzLCBbZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXRdLCAob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgb3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0ICYmIG91dHB1dENvbm5lY3Rpb25bMl0gPT09IGlucHV0LCB0cnVlKSkge1xuICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnMuYWRkKGV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBpbnB1dCwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoaW5zZXJ0RWxlbWVudEluU2V0KSA9PiB7XG4gICAgcmV0dXJuIChwYXNzaXZlSW5wdXRzLCBpbnB1dCwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IHBhc3NpdmVJbnB1dHMuZ2V0KHNvdXJjZSk7XG4gICAgICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwYXNzaXZlSW5wdXRzLnNldChzb3VyY2UsIG5ldyBTZXQoW1tvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXV0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucywgW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0ICYmIHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IGlucHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIGNvbnN0IGRpc2Nvbm5lY3QgPSAoKSA9PiB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0KTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfTtcbiAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtc2lsZW50LWNvbm5lY3Rpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYXVkaW9Xb3JrbGV0Tm9kZSkgPT4ge1xuICAgICAgICBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMobmF0aXZlQ29udGV4dCkuYWRkKGF1ZGlvV29ya2xldE5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGZmdFNpemU6IDIwNDgsXG4gICAgbWF4RGVjaWJlbHM6IC0zMCxcbiAgICBtaW5EZWNpYmVsczogLTEwMCxcbiAgICBzbW9vdGhpbmdUaW1lQ29uc3RhbnQ6IDAuOFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQW5hbHlzZXJOb2RlIGV4dGVuZHMgYXVkaW9uTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGFuYWx5c2VyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUFuYWx5c2VyTm9kZSwgYW5hbHlzZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlID0gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmZnRTaXplKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplO1xuICAgICAgICB9XG4gICAgICAgIHNldCBmZnRTaXplKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3lCaW5Db3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1heERlY2liZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWF4RGVjaWJlbHModmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgICAgIGNvbnN0IG1heERlY2liZWxzID0gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoISh2YWx1ZSA+IHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPSBtYXhEZWNpYmVscztcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBtaW5EZWNpYmVscygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHM7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG1pbkRlY2liZWxzKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzExODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIG1heERlY2liZWxzIGlzIG5vdCBtb3JlIHRoYW4gbWluRGVjaWJlbHMuXG4gICAgICAgICAgICBjb25zdCBtaW5EZWNpYmVscyA9IHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscztcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKCEodGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzID4gdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzID0gbWluRGVjaWJlbHM7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgc21vb3RoaW5nVGltZUNvbnN0YW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHNtb290aGluZ1RpbWVDb25zdGFudCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldEJ5dGVGcmVxdWVuY3lEYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEJ5dGVUaW1lRG9tYWluRGF0YShhcnJheSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmdldEJ5dGVUaW1lRG9tYWluRGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGbG9hdFRpbWVEb21haW5EYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFuYWx5c2VyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzT3duZWRCeUNvbnRleHQgPSAobmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZS5jb250ZXh0ID09PSBuYXRpdmVDb250ZXh0O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW93bmVkLWJ5LWNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQW5hbHlzZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQW5hbHlzZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQW5hbHlzZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZmZ0U2l6ZTogbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUsXG4gICAgICAgICAgICAgICAgICAgIG1heERlY2liZWxzOiBuYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMsXG4gICAgICAgICAgICAgICAgICAgIG1pbkRlY2liZWxzOiBuYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMsXG4gICAgICAgICAgICAgICAgICAgIHNtb290aGluZ1RpbWVDb25zdGFudDogbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQW5hbHlzZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbChuZXcgRmxvYXQzMkFycmF5KDEpLCAwLCAtMSk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUluZGV4U2l6ZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0luZGV4U2l6ZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC1zaXplLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUluZGV4U2l6ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2luZGV4LXNpemUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kID0gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEgPSAoKGdldENoYW5uZWxEYXRhKSA9PiB7XG4gICAgICAgIHJldHVybiAoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbERhdGEuY2FsbChhdWRpb0J1ZmZlciwgY2hhbm5lbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkoYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgdGVzdE5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgbGV0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBudWxsO1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0J1ZmZlciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzk5OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgTm90U3VwcG9ydGVkRXJyb3Igd2hlbiB0aGUgbnVtYmVyT2ZDaGFubmVscyBpcyB6ZXJvLiBCdXQgaXQgb25seSBkb2VzIGl0IHdoZW4gdXNpbmcgdGhlXG4gICAgICAgICAgICAgKiBmYWN0b3J5IGZ1bmN0aW9uLiBCdXQgc2luY2UgRmlyZWZveCBhbHNvIHN1cHBvcnRzIHRoZSBjb25zdHJ1Y3RvciBldmVyeXRoaW5nIHNob3VsZCBiZSBmaW5lLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICBjYWNoZVRlc3RSZXN1bHQodGVzdE5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0LCB0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQpXG4gICAgICAgICAgICAgICAgPyBuZXcgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9KVxuICAgICAgICAgICAgICAgIDogbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTk6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIHRoZSBudW1iZXJPZkNoYW5uZWxzIGlzIHplcm8uXG4gICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQoYXVkaW9CdWZmZXIpKSkge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBUaGlzIGRvZXMgdmlvbGF0ZSBhbGwgZ29vZCBwcmF0aWNlcyBidXQgaXQgaXMgbmVjZXNzYXJ5IHRvIGFsbG93IHRoaXMgQXVkaW9CdWZmZXIgdG8gYmUgdXNlZCB3aXRoIG5hdGl2ZVxuICAgICAgICAgICAgICogKE9mZmxpbmUpQXVkaW9Db250ZXh0cy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuICgoaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlID09PSAnb2JqZWN0JyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpID09PSBBdWRpb0J1ZmZlci5wcm90b3R5cGUpIHx8XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5oYXMoaW5zdGFuY2UpKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCA9IC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5leHBvcnQgY29uc3QgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgPSAtTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudHMuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBpc0FjdGl2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYWN0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGJ1ZmZlcjogbnVsbCxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgIGxvb3A6IGZhbHNlLFxuICAgIGxvb3BFbmQ6IDAsXG4gICAgbG9vcFN0YXJ0OiAwLFxuICAgIHBsYXliYWNrUmF0ZTogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9IGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyU2V0ID0gbWVyZ2VkT3B0aW9ucy5idWZmZXIgIT09IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbnVsbDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzM6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZSwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgYnVmZmVyKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICAvLyBCdWcgIzcyOiBPbmx5IENocm9tZSAmIEVkZ2UgZG8gbm90IGFsbG93IHRvIHJlYXNzaWduIHRoZSBidWZmZXIgeWV0LlxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzQnVmZmVyU2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyU2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcEVuZCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BFbmQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wU3RhcnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGxvb3BTdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBuYXRpdmVPbkVuZGVkICE9PSBudWxsICYmIG5hdGl2ZU9uRW5kZWQgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25FbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCh3aGVuLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLnN0YXJ0ID0gZHVyYXRpb24gPT09IHVuZGVmaW5lZCA/IFt3aGVuLCBvZmZzZXRdIDogW3doZW4sIG9mZnNldCwgZHVyYXRpb25dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gbnVsbDtcbiAgICAgICAgbGV0IHN0b3AgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgICAgICBsb29wOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BFbmQsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTdGFydDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydCxcbiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCguLi5zdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGxheWJhY2tSYXRlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBsYXliYWNrUmF0ZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdwbGF5YmFja1JhdGUnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQmlxdWFkRmlsdGVyTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlICYmICdnYWluJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0NvbnN0YW50U291cmNlTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ29mZnNldCcgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0dhaW5Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAhKCdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZSkgJiYgJ2dhaW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzT3NjaWxsYXRvck5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdkZXR1bmUnIGluIGF1ZGlvTm9kZSAmJiAnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc1N0ZXJlb1Bhbm5lck5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdwYW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSwgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSAoYXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSwgYXVkaW9QYXJhbSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9CdWZmZXJTb3VyY2VOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBpc0F1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGlzQmlxdWFkRmlsdGVyTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9iaXF1YWQtZmlsdGVyLW5vZGUnO1xuaW1wb3J0IHsgaXNDb25zdGFudFNvdXJjZU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvY29uc3RhbnQtc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgaXNHYWluTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9nYWluLW5vZGUnO1xuaW1wb3J0IHsgaXNPc2NpbGxhdG9yTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9vc2NpbGxhdG9yLW5vZGUnO1xuaW1wb3J0IHsgaXNTdGVyZW9QYW5uZXJOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL3N0ZXJlby1wYW5uZXItbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyA9IChhdWRpb05vZGUsIHRyYWNlKSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgYWN0aXZlSW5wdXRzLmZvckVhY2goKGNvbm5lY3Rpb25zKSA9PiBjb25uZWN0aW9ucy5mb3JFYWNoKChbc291cmNlXSkgPT4ge1xuICAgICAgICBpZiAoIXRyYWNlLmluY2x1ZGVzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zKHNvdXJjZSwgWy4uLnRyYWNlLCBhdWRpb05vZGVdKTtcbiAgICAgICAgfVxuICAgIH0pKTtcbiAgICBjb25zdCBhdWRpb1BhcmFtcyA9IGlzQXVkaW9CdWZmZXJTb3VyY2VOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgPyBbXG4gICAgICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgICAgIGF1ZGlvTm9kZS5wbGF5YmFja1JhdGVcbiAgICAgICAgXVxuICAgICAgICA6IGlzQXVkaW9Xb3JrbGV0Tm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICA/IEFycmF5LmZyb20oYXVkaW9Ob2RlLnBhcmFtZXRlcnMudmFsdWVzKCkpXG4gICAgICAgICAgICA6IGlzQmlxdWFkRmlsdGVyTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLlEsIGF1ZGlvTm9kZS5kZXR1bmUsIGF1ZGlvTm9kZS5mcmVxdWVuY3ksIGF1ZGlvTm9kZS5nYWluXVxuICAgICAgICAgICAgICAgIDogaXNDb25zdGFudFNvdXJjZU5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUub2Zmc2V0XVxuICAgICAgICAgICAgICAgICAgICA6IGlzR2Fpbk5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLmdhaW5dXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGlzT3NjaWxsYXRvck5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5kZXR1bmUsIGF1ZGlvTm9kZS5mcmVxdWVuY3ldXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc1N0ZXJlb1Bhbm5lck5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUucGFuXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFtdO1xuICAgIGZvciAoY29uc3QgYXVkaW9QYXJhbSBvZiBhdWRpb1BhcmFtcykge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSk7XG4gICAgICAgIGlmIChhdWRpb1BhcmFtQ29ubmVjdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYXVkaW9QYXJhbUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0cy5mb3JFYWNoKChbc291cmNlXSkgPT4gZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoc291cmNlLCB0cmFjZSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUoYXVkaW9Ob2RlKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVhY3RpdmF0ZS1hY3RpdmUtYXVkaW8tbm9kZS1pbnB1dC1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyB9IGZyb20gJy4vZGVhY3RpdmF0ZS1hY3RpdmUtYXVkaW8tbm9kZS1pbnB1dC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggPSAoY29udGV4dCkgPT4ge1xuICAgIGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zKGNvbnRleHQuZGVzdGluYXRpb24sIFtdKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc1ZhbGlkTGF0ZW5jeUhpbnQgPSAobGF0ZW5jeUhpbnQpID0+IHtcbiAgICByZXR1cm4gKGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgdHlwZW9mIGxhdGVuY3lIaW50ID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAodHlwZW9mIGxhdGVuY3lIaW50ID09PSAnc3RyaW5nJyAmJiAobGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCcgfHwgbGF0ZW5jeUhpbnQgPT09ICdpbnRlcmFjdGl2ZScgfHwgbGF0ZW5jeUhpbnQgPT09ICdwbGF5YmFjaycpKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtdmFsaWQtbGF0ZW5jeS1oaW50LmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IGlzVmFsaWRMYXRlbmN5SGludCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQ29udGV4dCBleHRlbmRzIGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTkyIFNhZmFyaSBkb2VzIHRocm93IGEgU3ludGF4RXJyb3IgaWYgdGhlIHNhbXBsZVJhdGUgaXMgbm90IHN1cHBvcnRlZC5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyICYmIGVyci5tZXNzYWdlID09PSAnc2FtcGxlUmF0ZSBpcyBub3QgaW4gcmFuZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTMxIFNhZmFyaSByZXR1cm5zIG51bGwgd2hlbiB0aGVyZSBhcmUgZm91ciBvdGhlciBBdWRpb0NvbnRleHRzIHJ1bm5pbmcgYWxyZWFkeS5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVVbmtub3duRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTEgT25seSBDaHJvbWUgYW5kIEVkZ2UgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIGxhdGVuY3lIaW50IGlzIGludmFsaWQuXG4gICAgICAgICAgICBpZiAoIWlzVmFsaWRMYXRlbmN5SGludChvcHRpb25zLmxhdGVuY3lIaW50KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFRoZSBwcm92aWRlZCB2YWx1ZSAnJHtvcHRpb25zLmxhdGVuY3lIaW50fScgaXMgbm90IGEgdmFsaWQgZW51bSB2YWx1ZSBvZiB0eXBlIEF1ZGlvQ29udGV4dExhdGVuY3lDYXRlZ29yeS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTUwIFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHNldHRpbmcgdGhlIHNhbXBsZVJhdGUuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zYW1wbGVSYXRlICE9PSB1bmRlZmluZWQgJiYgbmF0aXZlQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUgIT09IG9wdGlvbnMuc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVBdWRpb0NvbnRleHQsIDIpO1xuICAgICAgICAgICAgY29uc3QgeyBsYXRlbmN5SGludCB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGNvbnN0IHsgc2FtcGxlUmF0ZSB9ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQHRvZG8gVGhlIHZhbHVlcyBmb3IgJ2JhbGFuY2VkJywgJ2ludGVyYWN0aXZlJyBhbmQgJ3BsYXliYWNrJyBhcmUganVzdCBjb3BpZWQgZnJvbSBDaHJvbWUncyBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICAgIHRoaXMuX2Jhc2VMYXRlbmN5ID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5ID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICAgICA/IG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeVxuICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnYmFsYW5jZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IDUxMiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdpbnRlcmFjdGl2ZScgfHwgbGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMjU2IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdwbGF5YmFjaydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAxMDI0IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC8qXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQHRvZG8gVGhlIG1pbiAoMjU2KSBhbmQgbWF4ICgxNjM4NCkgdmFsdWVzIGFyZSB0YWtlbiBmcm9tIHRoZSBhbGxvd2VkIGJ1ZmZlclNpemUgdmFsdWVzIG9mIGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBTY3JpcHRQcm9jZXNzb3JOb2RlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1hdGgubWF4KDIsIE1hdGgubWluKDEyOCwgTWF0aC5yb3VuZCgobGF0ZW5jeUhpbnQgKiBzYW1wbGVSYXRlKSAvIDEyOCkpKSAqIDEyOCkgLyBzYW1wbGVSYXRlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQnVnICMxODg6IFNhZmFyaSB3aWxsIHNldCB0aGUgY29udGV4dCdzIHN0YXRlIHRvICdpbnRlcnJ1cHRlZCcgaW4gY2FzZSB0aGUgdXNlciBzd2l0Y2hlcyB0YWJzLlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5nYWluLnZhbHVlID0gMWUtMzc7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuY29ubmVjdCh0aGlzLl9uYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjMzQ6IENocm9tZSBhbmQgRWRnZSBwcmV0ZW5kIHRvIGJlIHJ1bm5pbmcgcmlnaHQgYXdheSwgYnV0IGZpcmUgYW4gb25zdGF0ZWNoYW5nZSBldmVudCB3aGVuIHRoZSBzdGF0ZSBhY3R1YWxseSBjaGFuZ2VzXG4gICAgICAgICAgICAgKiB0byAncnVubmluZycuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3N1c3BlbmRlZCc7XG4gICAgICAgICAgICAgICAgY29uc3QgcmV2b2tlU3RhdGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJhc2VMYXRlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VMYXRlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZSAhPT0gbnVsbCA/IHRoaXMuX3N0YXRlIDogdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGNsb3NlKCkge1xuICAgICAgICAgICAgLy8gQnVnICMzNTogRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgQXVkaW9Db250ZXh0IHdhcyBjbG9zZWQgYmVmb3JlLlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMzNDogSWYgdGhlIHN0YXRlIHdhcyBzZXQgdG8gc3VzcGVuZGVkIGJlZm9yZSBpdCBzaG91bGQgYmUgcmV2b2tlZCBub3cuXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVHYWluTm9kZSAhPT0gbnVsbCAmJiB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShtZWRpYUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYUVsZW1lbnQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYVN0cmVhbSB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlKG1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWVkaWFTdHJlYW1UcmFjayB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bWUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVByb21pc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VtZSgpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZXN1bWUoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NTogQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciBpbnN0ZWFkIG9mIGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCB8fCBlcnIuY29kZSA9PT0gMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VzcGVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3VzcGVuZCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9EZXN0aW5hdGlvbk5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaXNPZmZsaW5lKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIocmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBhdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2lzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGlzT2ZmbGluZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICM1MjogQ2hyb21lLCBFZGdlICYgU2FmYXJpIGRvIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gYXQgYWxsLlxuICAgICAgICAgICAgLy8gQnVnICM1NDogRmlyZWZveCBkb2VzIHRocm93IGFuIEluZGV4U2l6ZUVycm9yLlxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGRvZXMgbm90IGluaXRpYWxpemUgdGhlIG1heENoYW5uZWxDb3VudCBwcm9wZXJ0eSBjb3JyZWN0bHkuXG4gICAgICAgICAgICBpZiAodmFsdWUgPiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICM1MzogTm8gYnJvd3NlciBkb2VzIHRocm93IGFuIGV4Y2VwdGlvbiB5ZXQuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4Q2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciA9IChyZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb247XG4gICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICB9O1xuICAgIHJldHVybiB7XG4gICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tZGVzdGluYXRpb24tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkgPSAoY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldEZpcnN0U2FtcGxlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAoY29udGV4dCwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVMaXN0ZW5lciA9IG5hdGl2ZUNvbnRleHQubGlzdGVuZXI7XG4gICAgICAgIC8vIEJ1ZyAjMTE3OiBPbmx5IENocm9tZSAmIEVkZ2Ugc3VwcG9ydCB0aGUgbmV3IGludGVyZmFjZSBhbHJlYWR5LlxuICAgICAgICBjb25zdCBjcmVhdGVGYWtlQXVkaW9QYXJhbXMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGxldCBpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gWzAsIDAsIC0xLCAwLCAxLCAwXTtcbiAgICAgICAgICAgIGxldCBsYXN0UG9zaXRpb24gPSBbMCwgMCwgMF07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXNTY3JpcHRQcm9jZXNzb3JOb2RlQ3JlYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgMjU2LCA5LCAwKTtcbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKHsgaW5wdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA1KVxuICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldE9yaWVudGF0aW9uKC4uLm9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRvbiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDYpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA4KVxuICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0UG9zaXRpb24oLi4ucG9zaXRvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IHBvc2l0b247XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlU2V0T3JpZW50YXRpb24gPSAoaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb25baW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldE9yaWVudGF0aW9uKC4uLmxhc3RPcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlU2V0UG9zaXRpb24gPSAoaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb25baW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldFBvc2l0aW9uKC4uLmxhc3RQb3NpdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlRmFrZUF1ZGlvUGFyYW0gPSAoaW5wdXQsIGluaXRpYWxWYWx1ZSwgc2V0VmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBpbml0aWFsVmFsdWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoaXMgc2hvdWxkIGJlIHN0b3BwZWQgd2hlbiB0aGUgY29udGV4dCBpcyBjbG9zZWQuXG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQsICdkZWZhdWx0VmFsdWUnLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbml0aWFsVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjIgJiAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMgYW5kIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZFxuICAgICAgICAgICAgICAgICAqIG1pblZhbHVlIGZvciBHYWluTm9kZXMuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IGNyZWF0ZUF1ZGlvUGFyYW0oeyBjb250ZXh0IH0sIGlzT2ZmbGluZSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoYXVkaW9QYXJhbSwgJ3ZhbHVlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoYXVkaW9QYXJhbSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0LmNhbGwoYXVkaW9QYXJhbSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPT0gOSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTE3OiBVc2luZyBzZXRPcmllbnRhdGlvbigpIGFuZCBzZXRQb3NpdGlvbigpIGRvZXNuJ3Qgd29yayB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUgPSAoKGNhbmNlbEFuZEhvbGRBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2FuY2VsQW5kSG9sZEF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzID0gKChjYW5jZWxTY2hlZHVsZWRWYWx1ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2FuY2VsU2NoZWR1bGVkVmFsdWVzLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUgPSAoKGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUgPSAoKGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lID0gKChzZXRUYXJnZXRBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2V0VGFyZ2V0QXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lID0gKChzZXRWYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRWYWx1ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUgPSAoKHNldFZhbHVlQ3VydmVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2V0VmFsdWVDdXJ2ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZm9yd2FyZFg6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDAsIDAsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDApKSxcbiAgICAgICAgICAgICAgICBmb3J3YXJkWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMSwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMSkpLFxuICAgICAgICAgICAgICAgIGZvcndhcmRaOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgyLCAtMSwgY3JlYXRlU2V0T3JpZW50YXRpb24oMikpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNiwgMCwgY3JlYXRlU2V0UG9zaXRpb24oMCkpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNywgMCwgY3JlYXRlU2V0UG9zaXRpb24oMSkpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oOCwgMCwgY3JlYXRlU2V0UG9zaXRpb24oMikpLFxuICAgICAgICAgICAgICAgIHVwWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMywgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMykpLFxuICAgICAgICAgICAgICAgIHVwWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNCwgMSwgY3JlYXRlU2V0T3JpZW50YXRpb24oNCkpLFxuICAgICAgICAgICAgICAgIHVwWjogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNSwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oNSkpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB7IGZvcndhcmRYLCBmb3J3YXJkWSwgZm9yd2FyZFosIHBvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblosIHVwWCwgdXBZLCB1cFogfSA9IG5hdGl2ZUxpc3RlbmVyLmZvcndhcmRYID09PSB1bmRlZmluZWQgPyBjcmVhdGVGYWtlQXVkaW9QYXJhbXMoKSA6IG5hdGl2ZUxpc3RlbmVyO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZ2V0IGZvcndhcmRYKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZm9yd2FyZFkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFo7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25YO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblo7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBYO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBaKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFo7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1saXN0ZW5lci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvTm9kZSA9IChhdWRpb05vZGVPckF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gJ2NvbnRleHQnIGluIGF1ZGlvTm9kZU9yQXVkaW9QYXJhbTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi9hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gPSAob3V0cHV0Q29ubmVjdGlvbikgPT4ge1xuICAgIHJldHVybiBpc0F1ZGlvTm9kZShvdXRwdXRDb25uZWN0aW9uWzBdKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpbnNlcnRFbGVtZW50SW5TZXQgPSAoc2V0LCBlbGVtZW50LCBwcmVkaWNhdGUsIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICBmb3IgKGNvbnN0IGxtbnQgb2Ygc2V0KSB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUobG1udCkpIHtcbiAgICAgICAgICAgIGlmIChpZ25vcmVEdXBsaWNhdGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1RoZSBzZXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIHNpbWlsYXIgZWxlbWVudC4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQuYWRkKGVsZW1lbnQpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluc2VydC1lbGVtZW50LWluLXNldC5qcy5tYXAiLCJpbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5leHBvcnQgY29uc3QgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGluc2VydEVsZW1lbnRJblNldChhY3RpdmVJbnB1dHMsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuZXhwb3J0IGNvbnN0IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAocGFzc2l2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gcGFzc2l2ZUlucHV0cy5nZXQoc291cmNlKTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLnNldChzb3VyY2UsIG5ldyBTZXQoW1tvdXRwdXQsIGV2ZW50TGlzdGVuZXJdXSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCBbb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb24pID0+IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IG91dHB1dCwgaWdub3JlRHVwbGljYXRlcyk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgPSAobmF0aXZlQXVkaW9Ob2RlT3JOYXRpdmVBdWRpb05vZGVGYWtlcikgPT4ge1xuICAgIHJldHVybiAnaW5wdXRzJyBpbiBuYXRpdmVBdWRpb05vZGVPck5hdGl2ZUF1ZGlvTm9kZUZha2VyO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1ub2RlLWZha2VyLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuZXhwb3J0IGNvbnN0IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUpKSB7XG4gICAgICAgIGNvbnN0IGZha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLmlucHV0c1tpbnB1dF07XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KGZha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCAwKTtcbiAgICAgICAgcmV0dXJuIFtmYWtlTmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgMF07XG4gICAgfVxuICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICByZXR1cm4gW25hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0XTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24gPSAoYWN0aXZlSW5wdXRDb25uZWN0aW9ucywgc291cmNlLCBvdXRwdXQpID0+IHtcbiAgICBmb3IgKGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiBvZiBhY3RpdmVJbnB1dENvbm5lY3Rpb25zKSB7XG4gICAgICAgIGlmIChhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRDb25uZWN0aW9ucy5kZWxldGUoYWN0aXZlSW5wdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIHJldHVybiBhY3RpdmVJbnB1dENvbm5lY3Rpb247XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLmpzLm1hcCIsImltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vcGljay1lbGVtZW50LWZyb20tc2V0JztcbmV4cG9ydCBjb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIHJldHVybiBwaWNrRWxlbWVudEZyb21TZXQoYWN0aXZlSW5wdXRzLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3QgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSwgZXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgIGlmICghZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TGlzdGVuZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgZXhwZWN0ZWQgZXZlbnQgbGlzdGVuZXIuJyk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IGdldFZhbHVlRm9yS2V5KHBhc3NpdmVJbnB1dHMsIHNvdXJjZSk7XG4gICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9uID0gcGlja0VsZW1lbnRGcm9tU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0KTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLmRlbGV0ZShzb3VyY2UpO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9uO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5leHBvcnQgY29uc3QgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUgPSAobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlKSkge1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZS5pbnB1dHNbaW5wdXRdLCBvdXRwdXQsIDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXROYXRpdmVBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX05PREVfU1RPUkUsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX1BBUkFNX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldE5hdGl2ZUF1ZGlvUGFyYW0gPSAoYXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19QQVJBTV9TVE9SRSwgYXVkaW9QYXJhbSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBDWUNMRV9DT1VOVEVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzUGFydE9mQUN5Y2xlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBDWUNMRV9DT1VOVEVSUy5oYXMoYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wYXJ0LW9mLWEtY3ljbGUuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBpc1Bhc3NpdmVBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICFBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5oYXMoYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wYXNzaXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCA9IChuYXRpdmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGlzIGJ1ZyBleGlzdGVkIGluIFNhZmFyaSB1cCB1bnRpbCB2MTQuMC4yLiBTaW5jZSBBdWRpb1dvcmtsZXRzIHdlcmUgbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkgdW50aWwgdjE0LjEgdGhlIHByZXNlbmNlIG9mIHRoZVxuICAgICAgICAgKiBjb25zdHJ1Y3RvciBmb3IgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBjYW4gYmUgdXNlZCBoZXJlIHRvIHNraXAgdGhlIHRlc3QuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYW5hbHl6ZXIgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlU2NyaXB0UHJvY2Vzc29yKDI1NiwgMSwgMSk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmUgZGVwcmVjYXRpb25cbiAgICAgICAgICAgIGNvbnN0IGR1bW15ID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTU6IFNhZmFyaSBkb2VzIG5vdCBwbGF5IG9uZSBzYW1wbGUgYnVmZmVycy5cbiAgICAgICAgICAgIGNvbnN0IG9uZXMgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gb25lcy5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgICAgIGNoYW5uZWxEYXRhWzBdID0gMTtcbiAgICAgICAgICAgIGNoYW5uZWxEYXRhWzFdID0gMTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgICAgIHNvdXJjZS5idWZmZXIgPSBvbmVzO1xuICAgICAgICAgICAgc291cmNlLmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgc291cmNlLmNvbm5lY3QoYW5hbHl6ZXIpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIHNvdXJjZS5jb25uZWN0KGR1bW15KTtcbiAgICAgICAgICAgIHNvdXJjZS5kaXNjb25uZWN0KGR1bW15KTtcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgYW5hbHl6ZXIub25hdWRpb3Byb2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaG5ubER0ID0gZXZlbnQuaW5wdXRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmUgZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChjaG5ubER0LCAoc2FtcGxlKSA9PiBzYW1wbGUgPT09IDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc291cmNlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICBhbmFseXplci5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBzb3VyY2UuZGlzY29ubmVjdChhbmFseXplcik7XG4gICAgICAgICAgICAgICAgYW5hbHl6ZXIuZGlzY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UgPSAoY3ljbGVzLCB2aXNpdG9yKSA9PiB7XG4gICAgY29uc3QgY291bnRzID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3QgY3ljbGUgb2YgY3ljbGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgYXVkaW9Ob2RlIG9mIGN5Y2xlKSB7XG4gICAgICAgICAgICBjb25zdCBjb3VudCA9IGNvdW50cy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGNvdW50cy5zZXQoYXVkaW9Ob2RlLCBjb3VudCA9PT0gdW5kZWZpbmVkID8gMSA6IGNvdW50ICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY291bnRzLmZvckVhY2goKGNvdW50LCBhdWRpb05vZGUpID0+IHZpc2l0b3IoYXVkaW9Ob2RlLCBjb3VudCkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc05hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVBdWRpb05vZGVPckF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gJ2NvbnRleHQnIGluIG5hdGl2ZUF1ZGlvTm9kZU9yQXVkaW9QYXJhbTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QgPSAobmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QgPSAoKGNvbm5lY3QpID0+IHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZCBuby1pbmZlcnJhYmxlLXR5cGVzXG4gICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSBpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikgPyBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA6IGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBuZXcgY29ubmVjdGlvbiBvbmx5IGlmIHRoZSBjYWxscyB0byBjb25uZWN0IGFib3ZlIGRpZG4ndCB0aHJvdyBhbiBlcnJvci5cbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiA9IGNvbm5lY3Rpb25zLmdldChkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb24sIFt7IGlucHV0LCBvdXRwdXQgfV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5ldmVyeSgoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5pbnB1dCAhPT0gaW5wdXQgfHwgY29ubmVjdGlvbi5vdXRwdXQgIT09IG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLnB1c2goeyBpbnB1dCwgb3V0cHV0IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb05vZGUuY29ubmVjdC5iaW5kKG5hdGl2ZUF1ZGlvTm9kZSkpO1xuICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0ID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgIHJldHVybiAoZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICAgICAgZGlzY29ubmVjdC5hcHBseShuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmNsZWFyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtkZXN0aW5hdGlvbiwgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uXSBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZENvbm5lY3Rpb25zID0gY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmZpbHRlcigoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5vdXRwdXQgIT09IGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRDb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb24sIGZpbHRlcmVkQ29ubmVjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29ubmVjdGlvbnMuaGFzKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiA9IGNvbm5lY3Rpb25zLmdldChkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZENvbm5lY3Rpb25zID0gY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmZpbHRlcigoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5vdXRwdXQgIT09IG91dHB1dCAmJiAoY29ubmVjdGlvbi5pbnB1dCAhPT0gaW5wdXQgfHwgaW5wdXQgPT09IHVuZGVmaW5lZCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkQ29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuc2V0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIGZpbHRlcmVkQ29ubmVjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBbZGVzdGluYXRpb24sIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbl0gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZm9yRWFjaCgoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgY29ubmVjdGlvbi5vdXRwdXQsIGNvbm5lY3Rpb24uaW5wdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIGNvbm5lY3Rpb24ub3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9TVE9SRSwgRVZFTlRfTElTVEVORVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBpc0F1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uJztcbmltcG9ydCB7IGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uJztcbmltcG9ydCB7IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi4vaGVscGVycy9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzUGFydE9mQUN5Y2xlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1wYXJ0LW9mLWEtY3ljbGUnO1xuaW1wb3J0IHsgaXNQYXNzaXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5IH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeSc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UgfSBmcm9tICcuLi9oZWxwZXJzL3Zpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlJztcbmltcG9ydCB7IHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2QnO1xuY29uc3QgYWRkQ29ubmVjdGlvblRvQXVkaW9QYXJhbU9mQXVkaW9Db250ZXh0ID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaXNPZmZsaW5lKSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShzb3VyY2UpO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXIgPSAoaXNBY3RpdmUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpO1xuICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKGFjdGl2ZUlucHV0cywgc291cmNlLCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGlmIChpbnNlcnRFbGVtZW50SW5TZXQob3V0cHV0cywgW2Rlc3RpbmF0aW9uLCBvdXRwdXRdLCAob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgb3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCB0cnVlKSkge1xuICAgICAgICBldmVudExpc3RlbmVycy5hZGQoZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5jb25zdCBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvTm9kZSA9IChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCBhY3RpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24oYWN0aXZlSW5wdXRzW2lucHV0XSwgc291cmNlLCBvdXRwdXQpO1xuICAgIGlmIChhY3RpdmVJbnB1dENvbm5lY3Rpb24gPT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICByZXR1cm4gW3Bhc3NpdmVJbnB1dENvbm5lY3Rpb25bMl0sIGZhbHNlXTtcbiAgICB9XG4gICAgcmV0dXJuIFthY3RpdmVJbnB1dENvbm5lY3Rpb25bMl0sIHRydWVdO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9QYXJhbSA9IChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCBhY3RpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgIHJldHVybiBbcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSwgZmFsc2VdO1xuICAgIH1cbiAgICByZXR1cm4gW2FjdGl2ZUlucHV0Q29ubmVjdGlvblsyXSwgdHJ1ZV07XG59O1xuY29uc3QgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUgPSAoc291cmNlLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgW2xpc3RlbmVyLCBpc0FjdGl2ZV0gPSBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvTm9kZShzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KTtcbiAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlKHNvdXJjZSwgbGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmUgJiYgIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUoZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSksIGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbiksIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgY29uc3QgeyBhY3RpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkoZGVzdGluYXRpb24sIGFjdGl2ZUlucHV0cyk7XG4gICAgfVxufTtcbmNvbnN0IGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbSA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IFtsaXN0ZW5lciwgaXNBY3RpdmVdID0gZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb1BhcmFtKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgaWYgKGxpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZShzb3VyY2UsIGxpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlICYmICFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGdldE5hdGl2ZUF1ZGlvTm9kZShzb3VyY2UpLmRpc2Nvbm5lY3QoZ2V0TmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbiksIG91dHB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuY29uc3QgZGVsZXRlQW55Q29ubmVjdGlvbiA9IChzb3VyY2UsIGlzT2ZmbGluZSkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9ucyA9IFtdO1xuICAgIGZvciAoY29uc3Qgb3V0cHV0Q29ubmVjdGlvbiBvZiBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpIHtcbiAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXRDb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBkZXN0aW5hdGlvbnMucHVzaChvdXRwdXRDb25uZWN0aW9uWzBdKTtcbiAgICB9XG4gICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmNsZWFyKCk7XG4gICAgcmV0dXJuIGRlc3RpbmF0aW9ucztcbn07XG5jb25zdCBkZWxldGVDb25uZWN0aW9uQXRPdXRwdXQgPSAoc291cmNlLCBpc09mZmxpbmUsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9ucyA9IFtdO1xuICAgIGZvciAoY29uc3Qgb3V0cHV0Q29ubmVjdGlvbiBvZiBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpIHtcbiAgICAgICAgaWYgKG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkge1xuICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXRDb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZXN0aW5hdGlvbnMucHVzaChvdXRwdXRDb25uZWN0aW9uWzBdKTtcbiAgICAgICAgICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cy5kZWxldGUob3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlc3RpbmF0aW9ucztcbn07XG5jb25zdCBkZWxldGVDb25uZWN0aW9uVG9EZXN0aW5hdGlvbiA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpXG4gICAgICAgIC5maWx0ZXIoKG91dHB1dENvbm5lY3Rpb24pID0+IG91dHB1dENvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmXG4gICAgICAgIChvdXRwdXQgPT09IHVuZGVmaW5lZCB8fCBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpICYmXG4gICAgICAgIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dENvbm5lY3Rpb25bMl0gPT09IGlucHV0KSlcbiAgICAgICAgLm1hcCgob3V0cHV0Q29ubmVjdGlvbikgPT4ge1xuICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cy5kZWxldGUob3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiBvdXRwdXRDb25uZWN0aW9uWzBdO1xuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvciA9IChhZGRBdWRpb05vZGVDb25uZWN0aW9ucywgYWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRlY3JlbWVudEN5Y2xlQ291bnRlciwgZGV0ZWN0Q3ljbGVzLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVBdWRpb05vZGUsIGlzTmF0aXZlQXVkaW9QYXJhbSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Ob2RlIGV4dGVuZHMgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGlzQWN0aXZlLCBuYXRpdmVBdWRpb05vZGUsIGF1ZGlvTm9kZVJlbmRlcmVyKSB7XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUgPSBuYXRpdmVBdWRpb05vZGU7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTI6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRvIGRpc2Nvbm5lY3QgYSBzcGVjaWZpYyBkZXN0aW5hdGlvbi5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSAmJlxuICAgICAgICAgICAgICAgIHRydWUgIT09XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQVVESU9fTk9ERV9TVE9SRS5zZXQodGhpcywgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIEVWRU5UX0xJU1RFTkVSUy5zZXQodGhpcywgbmV3IFNldCgpKTtcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJyAmJiBpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHRoaXMsIGF1ZGlvTm9kZVJlbmRlcmVyLCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTppbnZhbGlkLXZvaWRcbiAgICAgICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE3NDogU2FmYXJpIGRvZXMgZXhwb3NlIGEgd3JvbmcgbnVtYmVyT2ZPdXRwdXRzIGZvciBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2Rlcy5cbiAgICAgICAgICAgIGlmIChvdXRwdXQgPCAwIHx8IG91dHB1dCA+PSB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KHRoaXMuX2NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSB8fCBpc05hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUodGhpcy5fbmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzUGFzc2l2ZSA9IGlzUGFzc2l2ZUF1ZGlvTm9kZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSB8fCBpc1Bhc3NpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KC4uLmNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnICYmICFpc1Bhc3NpdmUgJiYgaXNQYXNzaXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDE6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyB0aGUgY29ycmVjdCBleGNlcHRpb24gc28gZmFyLlxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzTmV3Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gYWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY0OiBPbmx5IEZpcmVmb3ggZGV0ZWN0cyBjeWNsZXMgc28gZmFyLlxuICAgICAgICAgICAgICAgIGlmIChpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvTm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXIoaXNPZmZsaW5lKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzczLCAjMTQ3ICYgIzE1MzogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdG8gY29ubmVjdCBhbiBpbnB1dCBzaWduYWwgdG8gdGhlIHBsYXliYWNrUmF0ZSBBdWRpb1BhcmFtIG9mIGFuXG4gICAgICAgICAgICAgKiBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuIFRoaXMgY2FuJ3QgYmUgZWFzaWx5IGRldGVjdGVkIGFuZCB0aGF0J3Mgd2h5IHRoZSBvdXRkYXRlZCBuYW1lIHByb3BlcnR5IGlzIHVzZWQgaGVyZSB0byBpZGVudGlmeVxuICAgICAgICAgICAgICogU2FmYXJpLiBJbiBhZGRpdGlvbiB0byB0aGF0IHRoZSBtYXhWYWx1ZSBwcm9wZXJ0eSBpcyB1c2VkIHRvIG9ubHkgZGV0ZWN0IHRoZSBhZmZlY3RlZCB2ZXJzaW9ucyBiZWxvdyB2MTQuMC4yLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9QYXJhbS5uYW1lID09PSAncGxheWJhY2tSYXRlJyAmJiBuYXRpdmVBdWRpb1BhcmFtLm1heFZhbHVlID09PSAxMDI0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lIHx8IGlzUGFzc2l2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU4OiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlzTmV3Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IGFkZENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW1PZkF1ZGlvQ29udGV4dCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICBpZiAoaXNOZXdDb25uZWN0aW9uVG9BdWRpb1BhcmFtKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXIoaXNPZmZsaW5lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSB7XG4gICAgICAgICAgICBsZXQgZGVzdGluYXRpb25zO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQodGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQW55Q29ubmVjdGlvbih0aGlzLCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPCAwIHx8IGRlc3RpbmF0aW9uT3JPdXRwdXQgPj0gdGhpcy5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQ29ubmVjdGlvbkF0T3V0cHV0KHRoaXMsIGlzT2ZmbGluZSwgZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0ICE9PSB1bmRlZmluZWQgJiYgKG91dHB1dCA8IDAgfHwgb3V0cHV0ID49IHRoaXMubnVtYmVyT2ZPdXRwdXRzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGUoZGVzdGluYXRpb25Pck91dHB1dCkgJiYgaW5wdXQgIT09IHVuZGVmaW5lZCAmJiAoaW5wdXQgPCAwIHx8IGlucHV0ID49IGRlc3RpbmF0aW9uT3JPdXRwdXQubnVtYmVyT2ZJbnB1dHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9ucyA9IGRlbGV0ZUNvbm5lY3Rpb25Ub0Rlc3RpbmF0aW9uKHRoaXMsIGlzT2ZmbGluZSwgZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRlc3RpbmF0aW9uIG9mIGRlc3RpbmF0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB2aXNpdEVhY2hBdWRpb05vZGVPbmNlKGN5Y2xlcywgZGVjcmVtZW50Q3ljbGVDb3VudGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBBdXRvbWF0aW9uRXZlbnRMaXN0IH0gZnJvbSAnYXV0b21hdGlvbi1ldmVudHMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW1GYWN0b3J5ID0gKGFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBhdWRpb1BhcmFtU3RvcmUsIGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciwgY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCwgY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW1PZk9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0sIG1heFZhbHVlID0gbnVsbCwgbWluVmFsdWUgPSBudWxsKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTk2IE9ubHkgU2FmYXJpIHNldHMgdGhlIGRlZmF1bHRWYWx1ZSB0byB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gbmF0aXZlQXVkaW9QYXJhbS52YWx1ZTtcbiAgICAgICAgY29uc3QgYXV0b21hdGlvbkV2ZW50TGlzdCA9IG5ldyBBdXRvbWF0aW9uRXZlbnRMaXN0KGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1SZW5kZXJlciA9IGlzQXVkaW9QYXJhbU9mT2ZmbGluZUF1ZGlvQ29udGV4dCA/IGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlcihhdXRvbWF0aW9uRXZlbnRMaXN0KSA6IG51bGw7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSB7XG4gICAgICAgICAgICBnZXQgZGVmYXVsdFZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXhWYWx1ZSA9PT0gbnVsbCA/IG5hdGl2ZUF1ZGlvUGFyYW0ubWF4VmFsdWUgOiBtYXhWYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pblZhbHVlID09PSBudWxsID8gbmF0aXZlQXVkaW9QYXJhbS5taW5WYWx1ZSA6IG1pblZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9QYXJhbS52YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM5ODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgeWV0IHRyZWF0IHRoZSB2YWx1ZSBzZXR0ZXIgbGlrZSBhIGNhbGwgdG8gc2V0VmFsdWVBdFRpbWUoKS5cbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FuY2VsQW5kSG9sZEF0VGltZShjYW5jZWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMyODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgeWV0IGltcGxlbWVudCBjYW5jZWxBbmRIb2xkQXRUaW1lKCkuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZShjYW5jZWxUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzTGFzdEV2ZW50ID0gQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRMYXN0RXZlbnQgPSBBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjYW5jZWxUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzTGFzdEV2ZW50ICE9PSBjdXJyZW50TGFzdEV2ZW50ICYmIGN1cnJlbnRMYXN0RXZlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlQ3VydmUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWVzLCBjdXJyZW50TGFzdEV2ZW50LnN0YXJ0VGltZSwgY3VycmVudExhc3RFdmVudC5kdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQoY2FuY2VsVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzQ1OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE4NzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShlbmRUaW1lKSB8fCBlbmRUaW1lIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTk0OiBGaXJlZm94IGRvZXMgbm90IGltcGxpY2l0bHkgY2FsbCBzZXRWYWx1ZUF0VGltZSgpIGlmIHRoZXJlIGlzIG5vIHByZXZpb3VzIGV2ZW50LlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5NTogRmlyZWZveCBkb2VzIG5vdCBpbXBsaWNpdGx5IGNhbGwgc2V0VmFsdWVBdFRpbWUoKSBpZiB0aGVyZSBpcyBubyBwcmV2aW91cyBldmVudC5cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSkpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZW5kVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIHN0YXJ0VGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgMTgzOiBTYWZhcmkgb25seSBhY2NlcHRzIGEgRmxvYXQzMkFycmF5LlxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlZFZhbHVlcyA9IHZhbHVlcyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IHZhbHVlcyA6IG5ldyBGbG9hdDMyQXJyYXkodmFsdWVzKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTUyOiBTYWZhcmkgZG9lcyBub3QgY29ycmVjdGx5IGludGVycG9sYXRlIHRoZSB2YWx1ZXMgb2YgdGhlIGN1cnZlLlxuICAgICAgICAgICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGVcbiAgICAgICAgICAgICAgICAgKiBleGlzdGVuY2Ugb2YgdGhlIHdlYmtpdEF1ZGlvQ29udGV4dCBpcyB1c2VkIGFzIGEgd29ya2Fyb3VuZCBoZXJlLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gc3RhcnRUaW1lICsgZHVyYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbXBsZVJhdGUgPSBhdWRpb05vZGUuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJzdFNhbXBsZSA9IE1hdGguY2VpbChzdGFydFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdFNhbXBsZSA9IE1hdGguZmxvb3IoZW5kVGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkludGVycG9sYXRlZFZhbHVlcyA9IGxhc3RTYW1wbGUgLSBmaXJzdFNhbXBsZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJwb2xhdGVkVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShudW1iZXJPZkludGVycG9sYXRlZFZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZJbnRlcnBvbGF0ZWRWYWx1ZXM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGhlb3JldGljSW5kZXggPSAoKGNvbnZlcnRlZFZhbHVlcy5sZW5ndGggLSAxKSAvIGR1cmF0aW9uKSAqICgoZmlyc3RTYW1wbGUgKyBpKSAvIHNhbXBsZVJhdGUgLSBzdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG93ZXJJbmRleCA9IE1hdGguZmxvb3IodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBwZXJJbmRleCA9IE1hdGguY2VpbCh0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBvbGF0ZWRWYWx1ZXNbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBjb252ZXJ0ZWRWYWx1ZXNbbG93ZXJJbmRleF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoMSAtICh0aGVvcmV0aWNJbmRleCAtIGxvd2VySW5kZXgpKSAqIGNvbnZlcnRlZFZhbHVlc1tsb3dlckluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIGNvbnZlcnRlZFZhbHVlc1t1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGludGVycG9sYXRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoaW50ZXJwb2xhdGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZU9mTGFzdFNhbXBsZSA9IGxhc3RTYW1wbGUgLyBzYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGltZU9mTGFzdFNhbXBsZSA8IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCBpbnRlcnBvbGF0ZWRWYWx1ZXNbaW50ZXJwb2xhdGVkVmFsdWVzLmxlbmd0aCAtIDFdLCB0aW1lT2ZMYXN0U2FtcGxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgY29udmVydGVkVmFsdWVzW2NvbnZlcnRlZFZhbHVlcy5sZW5ndGggLSAxXSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGNvbnZlcnRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoY29udmVydGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGF1ZGlvUGFyYW1TdG9yZS5zZXQoYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgIGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZS5zZXQoYXVkaW9QYXJhbSwgYXVkaW9Ob2RlKTtcbiAgICAgICAgYWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0sIGF1ZGlvUGFyYW1SZW5kZXJlcik7XG4gICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tcGFyYW0tZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyID0gKGF1dG9tYXRpb25FdmVudExpc3QpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICByZXBsYXkoYXVkaW9QYXJhbSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhdXRvbWF0aW9uRXZlbnQgb2YgYXV0b21hdGlvbkV2ZW50TGlzdCkge1xuICAgICAgICAgICAgICAgIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZW5kVGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbmRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRUYXJnZXQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgc3RhcnRUaW1lLCB0YXJnZXQsIHRpbWVDb25zdGFudCB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBzdGFydFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnc2V0VmFsdWVDdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkdXJhdGlvbiwgc3RhcnRUaW1lLCB2YWx1ZXMgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBhcHBseSBhbiB1bmtub3duIGF1dG9tYXRpb24uXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tcGFyYW0tcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNsYXNzIFJlYWRPbmx5TWFwIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ldyBNYXAocGFyYW1ldGVycyk7XG4gICAgfVxuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLnNpemU7XG4gICAgfVxuICAgIGVudHJpZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZW50cmllcygpO1xuICAgIH1cbiAgICBmb3JFYWNoKGNhbGxiYWNrLCB0aGlzQXJnID0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWUsIGtleSwgdGhpcykpO1xuICAgIH1cbiAgICBnZXQobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmdldChuYW1lKTtcbiAgICB9XG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5oYXMobmFtZSk7XG4gICAgfVxuICAgIGtleXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAua2V5cygpO1xuICAgIH1cbiAgICB2YWx1ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAudmFsdWVzKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVhZC1vbmx5LW1hcC5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IFJlYWRPbmx5TWFwIH0gZnJvbSAnLi4vcmVhZC1vbmx5LW1hcCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIC8vIEJ1ZyAjNjE6IFRoZSBjaGFubmVsQ291bnRNb2RlIHNob3VsZCBiZSAnbWF4JyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgYnV0IGlzIHNldCB0byAnZXhwbGljaXQnIHRvIGFjaGlldmUgY29uc2lzdGVudCBiZWhhdmlvci5cbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBudW1iZXJPZklucHV0czogMSxcbiAgICBudW1iZXJPZk91dHB1dHM6IDEsXG4gICAgcGFyYW1ldGVyRGF0YToge30sXG4gICAgcHJvY2Vzc29yT3B0aW9uczoge31cbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID0gKGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMsIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb1dvcmtsZXROb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgLy8gQnVnICMxOTE6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIGlmIHRoZSBvcHRpb25zIGFyZW4ndCBjbG9uYWJsZS5cbiAgICAgICAgICAgIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5KG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID0gTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NvckNvbnN0cnVjdG9yID0gbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID09PSBudWxsIHx8IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLmdldChuYW1lKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFsbG93IHRvIGNyZWF0ZSBhbiBBdWRpb1dvcmtsZXROb2RlIG9uIGEgY2xvc2VkIEF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBpc09mZmxpbmUgfHwgbmF0aXZlQ29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCdcbiAgICAgICAgICAgICAgICA/IG5hdGl2ZUNvbnRleHRcbiAgICAgICAgICAgICAgICA6IChfYSA9IGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IG5hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc09mZmxpbmUgPyBudWxsIDogY29udGV4dC5iYXNlTGF0ZW5jeSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYW1lLCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlcihuYW1lLCBtZXJnZWRPcHRpb25zLCBwcm9jZXNzb3JDb25zdHJ1Y3RvcikgOiBudWxsKSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQHRvZG8gQWRkIGEgbWVjaGFuaXNtIHRvIHN3aXRjaCBhbiBBdWRpb1dvcmtsZXROb2RlIHRvIHBhc3NpdmUgb25jZSB0aGUgcHJvY2VzcygpIGZ1bmN0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXRQcm9jZXNzb3JcbiAgICAgICAgICAgICAqIHJldHVybnMgZmFsc2UuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvV29ya2xldE5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gW107XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZm9yRWFjaCgobmF0aXZlQXVkaW9QYXJhbSwgbm0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMucHVzaChbbm0sIGF1ZGlvUGFyYW1dKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGU7XG4gICAgICAgICAgICB0aGlzLl9vbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtZXRlcnMgPSBuZXcgUmVhZE9ubHlNYXAocGFyYW1ldGVycyk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM4NiAmICM4NzogSW52b2tpbmcgdGhlIHJlbmRlcmVyIG9mIGFuIEF1ZGlvV29ya2xldE5vZGUgbWlnaHQgYmUgbmVjZXNzYXJ5IGlmIGl0IGhhcyBubyBkaXJlY3Qgb3IgaW5kaXJlY3QgY29ubmVjdGlvbiB0b1xuICAgICAgICAgICAgICogdGhlIGRlc3RpbmF0aW9uLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUobmF0aXZlQ29udGV4dCwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnModGhpcyk7XG4gICAgICAgICAgICBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9ucHJvY2Vzc29yZXJyb3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25wcm9jZXNzb3JlcnJvcih2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgPSB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlLm9ucHJvY2Vzc29yZXJyb3I7XG4gICAgICAgICAgICB0aGlzLl9vbnByb2Nlc3NvcmVycm9yID1cbiAgICAgICAgICAgICAgICBuYXRpdmVPblByb2Nlc3NvckVycm9yICE9PSBudWxsICYmIG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgPT09IHdyYXBwZWRMaXN0ZW5lclxuICAgICAgICAgICAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDogbmF0aXZlT25Qcm9jZXNzb3JFcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFyYW1ldGVycygpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9wYXJhbWV0ZXJzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhlIGRlZmluaXRpb24gdGhhdCBUeXBlU2NyaXB0IHVzZXMgb2YgdGhlIEF1ZGlvUGFyYW1NYXAgaXMgbGFja2luZyBtYW55IG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbWV0ZXJzO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3J0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUucG9ydDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBmdW5jdGlvbiBjb3B5RnJvbUNoYW5uZWwoYXVkaW9CdWZmZXIsIFxuLy8gQHRvZG8gVGhlcmUgaXMgY3VycmVudGx5IG5vIHdheSB0byBkZWZpbmUgc29tZXRoaW5nIGxpa2UgeyBbIGtleTogbnVtYmVyIHwgc3RyaW5nIF06IEZsb2F0MzJBcnJheSB9XG5wYXJlbnQsIGtleSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KSB7XG4gICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbChwYXJlbnRba2V5XSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKS5cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBwYXJlbnRba2V5XSA9IGNoYW5uZWxEYXRhLnNsaWNlKGJ1ZmZlck9mZnNldCwgYnVmZmVyT2Zmc2V0ICsgMTI4KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNsaWNlZElucHV0ID0gbmV3IEZsb2F0MzJBcnJheShjaGFubmVsRGF0YS5idWZmZXIsIGJ1ZmZlck9mZnNldCAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwgMTI4KTtcbiAgICAgICAgICAgIHBhcmVudFtrZXldLnNldChzbGljZWRJbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3B5LWZyb20tY2hhbm5lbC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY29weVRvQ2hhbm5lbCA9IChhdWRpb0J1ZmZlciwgcGFyZW50LCBrZXksIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCkgPT4ge1xuICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbChwYXJlbnRba2V5XSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlUb0NoYW5uZWwoKS5cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKS5zZXQocGFyZW50W2tleV0sIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29weS10by1jaGFubmVsLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOZXN0ZWRBcnJheXMgPSAoeCwgeSkgPT4ge1xuICAgIGNvbnN0IGFycmF5cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IGFycmF5ID0gW107XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IHR5cGVvZiB5ID09PSAnbnVtYmVyJyA/IHkgOiB5W2ldO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICBhcnJheS5wdXNoKG5ldyBGbG9hdDMyQXJyYXkoMTI4KSk7XG4gICAgICAgIH1cbiAgICAgICAgYXJyYXlzLnB1c2goYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXlzO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1uZXN0ZWQtYXJyYXlzLmpzLm1hcCIsImltcG9ydCB7IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KSA9PiB7XG4gICAgY29uc3Qgbm9kZVRvUHJvY2Vzc29yTWFwID0gZ2V0VmFsdWVGb3JLZXkoTk9ERV9UT19QUk9DRVNTT1JfTUFQUywgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KG5vZGVUb1Byb2Nlc3Nvck1hcCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzLm1hcCIsImltcG9ydCB7IGNvcHlGcm9tQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwnO1xuaW1wb3J0IHsgY29weVRvQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS10by1jaGFubmVsJztcbmltcG9ydCB7IGNyZWF0ZU5lc3RlZEFycmF5cyB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEF1ZGlvV29ya2xldFByb2Nlc3NvciB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuY29uc3QgcHJvY2Vzc0J1ZmZlciA9IGFzeW5jIChwcm94eSwgcmVuZGVyZWRCdWZmZXIsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMsIG91dHB1dENoYW5uZWxDb3VudCwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKSA9PiB7XG4gICAgLy8gQ2VpbCB0aGUgbGVuZ3RoIHRvIHRoZSBuZXh0IGZ1bGwgcmVuZGVyIHF1YW50dW0uXG4gICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICBjb25zdCBsZW5ndGggPSByZW5kZXJlZEJ1ZmZlciA9PT0gbnVsbCA/IE1hdGguY2VpbChwcm94eS5jb250ZXh0Lmxlbmd0aCAvIDEyOCkgKiAxMjggOiByZW5kZXJlZEJ1ZmZlci5sZW5ndGg7XG4gICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gb3B0aW9ucy5jaGFubmVsQ291bnQgKiBvcHRpb25zLm51bWJlck9mSW5wdXRzO1xuICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgY29uc3QgcHJvY2Vzc2VkQnVmZmVyID0gbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9PT0gMFxuICAgICAgICA/IG51bGxcbiAgICAgICAgOiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZk91dHB1dENoYW5uZWxzLCBsZW5ndGgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBwcm9jZXNzb3IgY29uc3RydWN0b3IuJyk7XG4gICAgfVxuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMocHJveHkpO1xuICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGF3YWl0IGdldEF1ZGlvV29ya2xldFByb2Nlc3NvcihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eSk7XG4gICAgY29uc3QgaW5wdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMsIG9wdGlvbnMuY2hhbm5lbENvdW50KTtcbiAgICBjb25zdCBvdXRwdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzLCBvdXRwdXRDaGFubmVsQ291bnQpO1xuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBBcnJheS5mcm9tKHByb3h5LnBhcmFtZXRlcnMua2V5cygpKS5yZWR1Y2UoKHBybXRycywgbmFtZSkgPT4gKHsgLi4ucHJtdHJzLCBbbmFtZV06IG5ldyBGbG9hdDMyQXJyYXkoMTI4KSB9KSwge30pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEyOCkge1xuICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZklucHV0cyA+IDAgJiYgcmVuZGVyZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChyZW5kZXJlZEJ1ZmZlciwgaW5wdXRzW2pdLCBrLCBrLCBpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQgJiYgcmVuZGVyZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmZvckVhY2goKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChyZW5kZXJlZEJ1ZmZlciwgcGFyYW1ldGVycywgbmFtZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgsIGkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgIGlmIChvdXRwdXRzW2pdW2tdLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0c1tqXVtrXSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbGx5RW1wdHlJbnB1dHMgPSBpbnB1dHMubWFwKChpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9Ob2RlQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzW2luZGV4XS5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVTb3VyY2VGbGFnID0gZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUoaSAvIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBhdWRpb1dvcmtsZXRQcm9jZXNzb3IucHJvY2Vzcyhwb3RlbnRpYWxseUVtcHR5SW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3B5VG9DaGFubmVsKHByb2Nlc3NlZEJ1ZmZlciwgb3V0cHV0c1tqXSwgaywgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2pdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYWN0aXZlU291cmNlRmxhZykge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcHJveHkuZGlzcGF0Y2hFdmVudChuZXcgRXJyb3JFdmVudCgncHJvY2Vzc29yZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgY29sbm86IGVycm9yLmNvbG5vLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBlcnJvci5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICBsaW5lbm86IGVycm9yLmxpbmVubyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcHJvY2Vzc2VkQnVmZmVyO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBkZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChuYW1lLCBvcHRpb25zLCBwcm9jZXNzb3JDb25zdHJ1Y3RvcikgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgbGV0IG5hdGl2ZU91dHB1dE5vZGVzID0gbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxDb3VudCA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpXG4gICAgICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgICAgIDogQXJyYXkuZnJvbShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgICAgICAvLyBCdWcgIzYxOiBPbmx5IENocm9tZSwgRWRnZSAmIEZpcmVmb3ggaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB5ZXQuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyksXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJveHkubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBvdXRwdXRDaGFubmVsQ291bnRbaV1cbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY29ubmVjdCA9IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMpO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QgPSBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLmJpbmQobnVsbCwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVPdXRwdXROb2RlcyA9IFtvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMsIG91dHB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFuYXRpdmVBdWRpb1dvcmtsZXROb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBuZXcgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPdXRwdXROb2RlcyA9PT0gbnVsbCA/IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgOiBuYXRpdmVPdXRwdXROb2Rlc1syXSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlT3V0cHV0Tm9kZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBwcm9jZXNzb3IgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGdldHMgbm90IGluaXRpYWxpemVkIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gcHJveHkuY2hhbm5lbENvdW50ICogcHJveHkubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mUGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWQgPyAwIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJCdWZmZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IobnVtYmVyT2ZDaGFubmVscywgXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDZWlsIHRoZSBsZW5ndGggdG8gdGhlIG5leHQgZnVsbCByZW5kZXIgcXVhbnR1bS5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmNlaWwocHJveHkuY29udGV4dC5sZW5ndGggLyAxMjgpICogMTI4LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGVzID0gYXdhaXQgUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShwcm94eS5wYXJhbWV0ZXJzLnZhbHVlcygpKS5tYXAoYXN5bmMgKGF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogYXVkaW9QYXJhbS52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24ocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycylcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGosIGkgKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBjb25zdGFudFNvdXJjZU5vZGVdIG9mIGNvbnN0YW50U291cmNlTm9kZXMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChnYWluTm9kZXMubWFwKChnYWluTm9kZSkgPT4gcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBnYWluTm9kZSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9IHByb2Nlc3NCdWZmZXIocHJveHksIG51bWJlck9mQ2hhbm5lbHMgPT09IDAgPyBudWxsIDogYXdhaXQgcmVuZGVyQnVmZmVyKCksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMsIG91dHB1dENoYW5uZWxDb3VudCwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkQnVmZmVyID0gYXdhaXQgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgW291dHB1dENoYW5uZWxTcGxpdHRlck5vZGUsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcywgb3V0cHV0R2Fpbk5vZGVdID0gbmF0aXZlT3V0cHV0Tm9kZXM7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gcHJvY2Vzc2VkQnVmZmVyO1xuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IHByb3h5Lm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlID0gb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBqLCBqKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dEdhaW5Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb1dvcmtsZXROb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW25tLCBhdWRpb1BhcmFtXSBvZiBwcm94eS5wYXJhbWV0ZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIFxuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmdldChubSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW25tLCBhdWRpb1BhcmFtXSBvZiBwcm94eS5wYXJhbWV0ZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhlIGRlZmluaXRpb24gdGhhdCBUeXBlU2NyaXB0IHVzZXMgb2YgdGhlIEF1ZGlvUGFyYW1NYXAgaXMgbGFja2luZyBtYW55IG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5nZXQobm0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KTtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb1dvcmtsZXROb2RlT3JHYWluTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb1dvcmtsZXROb2RlT3JHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChhZGRBdWRpb1dvcmtsZXRNb2R1bGUsIGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IsIGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yLCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IsIGRlY29kZUF1ZGlvRGF0YSwgZGVsYXlOb2RlQ29uc3RydWN0b3IsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciwgZ2Fpbk5vZGVDb25zdHJ1Y3RvciwgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yLCBwYW5uZXJOb2RlQ29uc3RydWN0b3IsIHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yLCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IsIHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQmFzZUF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgc3VwZXIoX25hdGl2ZUNvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dCA9IF9uYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgdGhpcy5fYXVkaW9Xb3JrbGV0ID1cbiAgICAgICAgICAgICAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE1vZHVsZTogKG1vZHVsZVVSTCwgb3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRBdWRpb1dvcmtsZXRNb2R1bGUodGhpcywgbW9kdWxlVVJMLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgYXVkaW9Xb3JrbGV0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F1ZGlvV29ya2xldDtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQmlxdWFkRmlsdGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cyA9IDYpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG51bWJlck9mSW5wdXRzIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMgPSA2KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG51bWJlck9mT3V0cHV0cyB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ29udm9sdmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lID0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBkZWxheU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1heERlbGF5VGltZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVHYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBnYWluTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUlJUkZpbHRlcihmZWVkZm9yd2FyZCwgZmVlZGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgZmVlZGJhY2ssIGZlZWRmb3J3YXJkIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBwYW5uZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcsIGNvbnN0cmFpbnRzID0geyBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2UgfSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBwZXJpb2RpY1dhdmVDb25zdHJ1Y3Rvcih0aGlzLCB7IC4uLmNvbnN0cmFpbnRzLCBpbWFnLCByZWFsIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVdhdmVTaGFwZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSwgc3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjb2RlQXVkaW9EYXRhKHRoaXMuX25hdGl2ZUNvbnRleHQsIGF1ZGlvRGF0YSkudGhlbigoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN1Y2Nlc3NDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBlcnJvckNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIFE6IDEsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkZXR1bmU6IDAsXG4gICAgZnJlcXVlbmN5OiAzNTAsXG4gICAgZ2FpbjogMCxcbiAgICB0eXBlOiAnbG93cGFzcydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBCaXF1YWRGaWx0ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBiaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBiaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM4MDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX1EgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgLy8gQnVnICM3ODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZGV0dW5lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lLCAxMjAwICogTWF0aC5sb2cyKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSwgLTEyMDAgKiBNYXRoLmxvZzIoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzc6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZSBmb3IgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3ksIGNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsIDApO1xuICAgICAgICAgICAgLy8gQnVnICM3OTogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZ2FpbiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4sIDQwICogTWF0aC5sb2cxMChNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCksIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGV0dW5lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldHVuZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZnJlcXVlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZ2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nYWluO1xuICAgICAgICB9XG4gICAgICAgIGdldCBRKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX1E7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlO1xuICAgICAgICB9XG4gICAgICAgIHNldCB0eXBlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg5OiBTYWZhcmkgZG9lcyB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvci5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNjg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgcGFyYW1ldGVycyBkaWZmZXIgaW4gdGhlaXIgbGVuZ3RoLlxuICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIFE6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZXR1bmU6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQmlxdWFkRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LlEsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LlEsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNhY2hlVGVzdFJlc3VsdCA9IChvbmdvaW5nVGVzdHMsIHRlc3RSZXN1bHRzKSA9PiB7XG4gICAgcmV0dXJuICh0ZXN0ZXIsIHRlc3QpID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVkVGVzdFJlc3VsdCA9IHRlc3RSZXN1bHRzLmdldCh0ZXN0ZXIpO1xuICAgICAgICBpZiAoY2FjaGVkVGVzdFJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkVGVzdFJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvbmdvaW5nVGVzdCA9IG9uZ29pbmdUZXN0cy5nZXQodGVzdGVyKTtcbiAgICAgICAgaWYgKG9uZ29pbmdUZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBvbmdvaW5nVGVzdDtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3luY2hyb25vdXNUZXN0UmVzdWx0ID0gdGVzdCgpO1xuICAgICAgICAgICAgaWYgKHN5bmNocm9ub3VzVGVzdFJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBvbmdvaW5nVGVzdHMuc2V0KHRlc3Rlciwgc3luY2hyb25vdXNUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3luY2hyb25vdXNUZXN0UmVzdWx0XG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKGZpbmFsVGVzdFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvbmdvaW5nVGVzdHMuZGVsZXRlKHRlc3Rlcik7XG4gICAgICAgICAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIGZpbmFsVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaW5hbFRlc3RSZXN1bHQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXN0UmVzdWx0cy5zZXQodGVzdGVyLCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQpO1xuICAgICAgICAgICAgcmV0dXJuIHN5bmNocm9ub3VzVGVzdFJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICB0ZXN0UmVzdWx0cy5zZXQodGVzdGVyLCBmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhY2hlLXRlc3QtcmVzdWx0LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgbnVtYmVyT2ZJbnB1dHM6IDZcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDaGFubmVsTWVyZ2VyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLW1lcmdlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb05vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mSW5wdXRzXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLW1lcmdlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogNixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICBudW1iZXJPZk91dHB1dHM6IDZcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENoYW5uZWxTcGxpdHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb05vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IG5hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hhbm5lbC1zcGxpdHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtID0gKHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICByZXR1cm4gcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdC1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAob3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICBjb25zdCBvdXRwdXRBdWRpb05vZGUgPSBvdXRwdXRBdWRpb05vZGVzW291dHB1dF07XG4gICAgICAgIGlmIChvdXRwdXRBdWRpb05vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIDAsIGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIDApO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB0cnVlO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdGVkLW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBvZmZzZXQ6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENvbnN0YW50U291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyID0gY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM2MiAmICM3NDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2RlcyBhbmQgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlXG4gICAgICAgICAgICAgKiBmb3IgR2Fpbk5vZGVzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvZmZzZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBuYXRpdmVPbkVuZGVkICE9PSBudWxsICYmIG5hdGl2ZU9uRW5kZWQgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25FbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIuc3RhcnQgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldC52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RvcChzdG9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9mZnNldCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vZmZzZXQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2V0IHN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RvcCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0b3AgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nID0gKHVuaXQzMkFycmF5KSA9PiB7XG4gICAgcmV0dXJuICh2YWx1ZSkgPT4ge1xuICAgICAgICB1bml0MzJBcnJheVswXSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdW5pdDMyQXJyYXlbMF07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBidWZmZXI6IG51bGwsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDb252b2x2ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBjb252b2x2ZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDb252b2x2ZXJOb2RlLCBjb252b2x2ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUgPSBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgICAgICAgICAgaWYgKG1lcmdlZE9wdGlvbnMuYnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgbWVyZ2VkT3B0aW9ucy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgYnVmZmVyKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9IHZhbHVlO1xuICAgICAgICAgICAgLy8gQnVnICMxMTU6IFNhZmFyaSBkb2VzIG5vdCBhbGxvdyB0byBzZXQgdGhlIGJ1ZmZlciB0byBudWxsLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsICYmIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9PT0gbnVsbCA/IDAgOiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbm9ybWFsaXplKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb252b2x2ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQ29udm9sdmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnZvbHZlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVDb252b2x2ZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29udm9sdmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG5hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVOb3JtYWxpemF0aW9uOiAhbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVDb252b2x2ZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVDb252b2x2ZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZvbHZlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgLy8gQnVnICMxNDMsICMxNDQgJiAjMTQ2OiBTYWZhcmkgdGhyb3dzIGEgU3ludGF4RXJyb3Igd2hlbiBudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGggb3Igc2FtcGxlUmF0ZSBhcmUgaW52YWxpZC5cbiAgICAgICAgICAgIGlmIChlcnIubmFtZSA9PT0gJ1N5bnRheEVycm9yJykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEYXRhQ2xvbmVFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdEYXRhQ2xvbmVFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YS1jbG9uZS1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgZGV0YWNoQXJyYXlCdWZmZXIgPSAoYXJyYXlCdWZmZXIpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb3NlQW5kUmVzb2x2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHBvcnQyLm9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICAgICAgcG9ydDIuY2xvc2UoKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgcG9ydDIub25tZXNzYWdlID0gKCkgPT4gY2xvc2VBbmRSZXNvbHZlKCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3J0MS5wb3N0TWVzc2FnZShhcnJheUJ1ZmZlciwgW2FycmF5QnVmZmVyXSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNsb3NlQW5kUmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGV0YWNoLWFycmF5LWJ1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBkZXRhY2hBcnJheUJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZGV0YWNoLWFycmF5LWJ1ZmZlcic7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY29kZUF1ZGlvRGF0YSA9IChhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZURhdGFDbG9uZUVycm9yLCBjcmVhdGVFbmNvZGluZ0Vycm9yLCBkZXRhY2hlZEFycmF5QnVmZmVycywgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVDb250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHRlc3RQcm9taXNlU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcykgPT4ge1xuICAgIHJldHVybiAoYW55Q29udGV4dCwgYXVkaW9EYXRhKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBpc05hdGl2ZUNvbnRleHQoYW55Q29udGV4dCkgPyBhbnlDb250ZXh0IDogZ2V0TmF0aXZlQ29udGV4dChhbnlDb250ZXh0KTtcbiAgICAgICAgLy8gQnVnICM0MzogT25seSBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYSBEYXRhQ2xvbmVFcnJvci5cbiAgICAgICAgaWYgKGRldGFjaGVkQXJyYXlCdWZmZXJzLmhhcyhhdWRpb0RhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBlcnIgPSBjcmVhdGVEYXRhQ2xvbmVFcnJvcigpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGF1ZGlvRGF0YSBwYXJhbWV0ZXIgbWF5YmUgb2YgYSB0eXBlIHdoaWNoIGNhbid0IGJlIGFkZGVkIHRvIGEgV2Vha1NldC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRldGFjaGVkQXJyYXlCdWZmZXJzLmFkZChhdWRpb0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgeWV0LlxuICAgICAgICBpZiAoY2FjaGVUZXN0UmVzdWx0KHRlc3RQcm9taXNlU3VwcG9ydCwgKCkgPT4gdGVzdFByb21pc2VTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSkudGhlbigoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMzogU2FmYXJpIGRvZXMgbmV1dGVyIHRoZSBBcnJheUJ1ZmZlci5cbiAgICAgICAgICAgICAgICBkZXRhY2hBcnJheUJ1ZmZlcihhdWRpb0RhdGEpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NzogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0aGUgYnVmZmVyT2Zmc2V0IHRvIGJlIG91dC1vZi1ib3VuZHMuXG4gICAgICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQoYXVkaW9CdWZmZXIpKSkge1xuICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3QgcmV0dXJuIGEgUHJvbWlzZSB5ZXQuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb21wbGV0ZSA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMzogU2FmYXJpIGRvZXMgbmV1dGVyIHRoZSBBcnJheUJ1ZmZlci5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBkZXRhY2hBcnJheUJ1ZmZlcihhdWRpb0RhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGZhaWwgPSAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgY29tcGxldGUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBCdWcgIzI2OiBTYWZhcmkgdGhyb3dzIGEgc3luY2hyb25vdXMgZXJyb3IuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTogU2FmYXJpIHJlcXVpcmVzIGEgc3VjY2Vzc0NhbGxiYWNrLlxuICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSwgKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlKCkudGhlbigoKSA9PiByZXNvbHZlKGF1ZGlvQnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ6IFNhZmFyaSByZXR1cm5zIG51bGwgaW5zdGVhZCBvZiBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFpbChjcmVhdGVFbmNvZGluZ0Vycm9yKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFpbChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgZmFpbChlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlY29kZS1hdWRpby1kYXRhLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uJztcbmV4cG9ydCBjb25zdCBjcmVhdGVEZWNyZW1lbnRDeWNsZUNvdW50ZXIgPSAoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXJzLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBnZXROYXRpdmVDb250ZXh0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGNvdW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGN5Y2xlQ291bnRlciA9IGN5Y2xlQ291bnRlcnMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgIGlmIChjeWNsZUNvdW50ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBleHBlY3RlZCBjeWNsZSBjb3VudC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChhdWRpb05vZGUuY29udGV4dCk7XG4gICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gY291bnQpIHtcbiAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuZGVsZXRlKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiBpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlU291cmNlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dFsxXSwgb3V0cHV0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0ob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSwgb3V0cHV0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY3ljbGVDb3VudGVyIC0gY291bnQpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWNyZW1lbnQtY3ljbGUtY291bnRlci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkZWxheVRpbWU6IDAsXG4gICAgbWF4RGVsYXlUaW1lOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGF5Tm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIERlbGF5Tm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZSA9IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbGF5Tm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyKG1lcmdlZE9wdGlvbnMubWF4RGVsYXlUaW1lKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZURlbGF5Tm9kZSwgZGVsYXlOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgbWVyZ2VkT3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZWxheVRpbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVsYXlUaW1lO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChtYXhEZWxheVRpbWUpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlRGVsYXlOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlRGVsYXlOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVEZWxheU5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVEZWxheU5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZWxheVRpbWU6IG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1heERlbGF5VGltZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlRGVsYXlOb2RlID0gY3JlYXRlTmF0aXZlRGVsYXlOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZWxheVRpbWUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGVsYXlUaW1lLCBuYXRpdmVEZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZURlbGF5Tm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlID0gcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVEZWxheU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZURlbGF5Tm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKHBpY2tFbGVtZW50RnJvbVNldCkgPT4ge1xuICAgIHJldHVybiAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgcmV0dXJuIHBpY2tFbGVtZW50RnJvbVNldChhY3RpdmVJbnB1dHNbaW5wdXRdLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSAoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBhdWRpb1dvcmtsZXROb2RlKSA9PiB7XG4gICAgICAgIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVDb250ZXh0KS5kZWxldGUoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzRGVsYXlOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZGVsYXlUaW1lJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsYXktbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzRGVsYXlOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2RlbGF5LW5vZGUnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURldGVjdEN5Y2xlcyA9IChhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRWYWx1ZUZvcktleSkgPT4ge1xuICAgIHJldHVybiBmdW5jdGlvbiBkZXRlY3RDeWNsZXMoY2hhaW4sIG5leHRMaW5rKSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvTm9kZSA9IGlzQXVkaW9Ob2RlKG5leHRMaW5rKSA/IG5leHRMaW5rIDogZ2V0VmFsdWVGb3JLZXkoYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBuZXh0TGluayk7XG4gICAgICAgIGlmIChpc0RlbGF5Tm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYWluWzBdID09PSBhdWRpb05vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBbY2hhaW5dO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFpbi5pbmNsdWRlcyhhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShvdXRwdXRzKVxuICAgICAgICAgICAgLm1hcCgob3V0cHV0Q29ubmVjdGlvbikgPT4gZGV0ZWN0Q3ljbGVzKFsuLi5jaGFpbiwgYXVkaW9Ob2RlXSwgb3V0cHV0Q29ubmVjdGlvblswXSkpXG4gICAgICAgICAgICAucmVkdWNlKChtZXJnZWRDeWNsZXMsIG5lc3RlZEN5Y2xlcykgPT4gbWVyZ2VkQ3ljbGVzLmNvbmNhdChuZXN0ZWRDeWNsZXMpLCBbXSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXRlY3QtY3ljbGVzLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmNvbnN0IGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXggPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZSA9IG91dHB1dEF1ZGlvTm9kZXNbb3V0cHV0XTtcbiAgICBpZiAob3V0cHV0QXVkaW9Ob2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZTtcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAob3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb25Pck91dHB1dCA9IHVuZGVmaW5lZCwgb3V0cHV0ID0gdW5kZWZpbmVkLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb25Pck91dHB1dCkuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSkge1xuICAgICAgICAgICAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIDAsIGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGVzLmZvckVhY2goKG91dHB1dEF1ZGlvTm9kZSkgPT4gb3V0cHV0QXVkaW9Ob2RlLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGF0dGFjazogMC4wMDMsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGtuZWU6IDMwLFxuICAgIHJhdGlvOiAxMixcbiAgICByZWxlYXNlOiAwLjI1LFxuICAgIHRocmVzaG9sZDogLTI0XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBEeW5hbWljc0NvbXByZXNzb3JOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBkeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fYXR0YWNrID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgIHRoaXMuX2tuZWUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgICAgICAgICAgdGhpcy5fcmF0aW8gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICB0aGlzLl9yZWxlYXNlID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVsZWFzZSk7XG4gICAgICAgICAgICB0aGlzLl90aHJlc2hvbGQgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMC4wMDYpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBhdHRhY2soKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXR0YWNrO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTA4OiBTYWZhcmkgYWxsb3dzIGEgY2hhbm5lbENvdW50IG9mIHRocmVlIGFuZCBhYm92ZSB3aGljaCBpcyB3aHkgdGhlIGdldHRlciBhbmQgc2V0dGVyIG5lZWRzIHRvIGJlIG92ZXJ3cml0dGVuIGhlcmUuXG4gICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNDaGFubmVsQ291bnQgPSB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQgPSBwcmV2aW91c0NoYW5uZWxDb3VudDtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTA5OiBPbmx5IENocm9tZSBhbmQgRmlyZWZveCBkaXNhbGxvdyBhIGNoYW5uZWxDb3VudE1vZGUgb2YgJ21heCcgeWV0IHdoaWNoIGlzIHdoeSB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgbmVlZHMgdG8gYmVcbiAgICAgICAgICogb3ZlcndyaXR0ZW4gaGVyZS5cbiAgICAgICAgICovXG4gICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNDaGFubmVsQ291bnQgPSB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSBwcmV2aW91c0NoYW5uZWxDb3VudDtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBrbmVlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2tuZWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJhdGlvKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JhdGlvO1xuICAgICAgICB9XG4gICAgICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzExMTogU2FmYXJpIHJldHVybnMgYW4gQXVkaW9QYXJhbSBpbnN0ZWFkIG9mIGEgbnVtYmVyLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbi52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWR1Y3Rpb24udmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWR1Y3Rpb247XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlbGVhc2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVsZWFzZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdGhyZXNob2xkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RocmVzaG9sZDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZVxuICAgICAgICAgICAgICogY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAga25lZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByYXRpbzogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpby52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuYXR0YWNrLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjayk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5rbmVlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmF0aW8sIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmF0aW8pO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmVsZWFzZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnRocmVzaG9sZCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuYXR0YWNrLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjayk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkua25lZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yYXRpbywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmVsZWFzZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS50aHJlc2hvbGQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUVuY29kaW5nRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnRW5jb2RpbmdFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZW5jb2RpbmctZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV2YWx1YXRlU291cmNlID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoc291cmNlKSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWQgPSB3aW5kb3cuZG9jdW1lbnQuaGVhZDtcbiAgICAgICAgaWYgKGhlYWQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICAgICAgLy8gQHRvZG8gU2FmYXJpIGRvZXNuJ3QgbGlrZSBVUkxzIHdpdGggYSB0eXBlIG9mICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04Jy5cbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbc291cmNlXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcgfSk7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxPbkVycm9ySGFuZGxlciA9IHdpbmRvdy5vbmVycm9yO1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5vbmVycm9yID0gb3JpZ2luYWxPbkVycm9ySGFuZGxlcjtcbiAgICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgd2luZG93Lm9uZXJyb3IgPSAobWVzc2FnZSwgc3JjLCBsaW5lbm8sIGNvbG5vLCBlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIEVkZ2UgdGhpbmtzIHRoZSBzb3VyY2UgaXMgdGhlIG9uZSBvZiB0aGUgaHRtbCBkb2N1bWVudC5cbiAgICAgICAgICAgICAgICBpZiAoc3JjID09PSB1cmwgfHwgKHNyYyA9PT0gd2luZG93LmxvY2F0aW9uLmhyZWYgJiYgbGluZW5vID09PSAxICYmIGNvbG5vID09PSAxKSkge1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxPbkVycm9ySGFuZGxlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxPbkVycm9ySGFuZGxlcihtZXNzYWdlLCBzcmMsIGxpbmVubywgY29sbm8sIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsKCk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsKCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgPSB1cmw7XG4gICAgICAgICAgICBzY3JpcHQudHlwZSA9ICdtb2R1bGUnO1xuICAgICAgICAgICAgaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZhbHVhdGUtc291cmNlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yID0gKHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEV2ZW50VGFyZ2V0IHtcbiAgICAgICAgY29uc3RydWN0b3IoX25hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldCA9IF9uYXRpdmVFdmVudFRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwZWRFdmVudExpc3RlbmVyID0gdGhpcy5fbGlzdGVuZXJzLmdldChsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgaWYgKHdyYXBwZWRFdmVudExpc3RlbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVycy5zZXQobGlzdGVuZXIsIHdyYXBwZWRFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIHdyYXBwZWRFdmVudExpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSBsaXN0ZW5lciA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRoaXMuX2xpc3RlbmVycy5nZXQobGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHdyYXBwZWRFdmVudExpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGN1cnJlbnRUaW1lLCBzYW1wbGVSYXRlLCBmbikgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3csIHtcbiAgICAgICAgICAgIGN1cnJlbnRGcmFtZToge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKGN1cnJlbnRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGN1cnJlbnRUaW1lOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgd2luZG93LmN1cnJlbnRGcmFtZTtcbiAgICAgICAgICAgICAgICBkZWxldGUgd2luZG93LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1leHBvc2UtY3VycmVudC1mcmFtZS1hbmQtY3VycmVudC10aW1lLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVGZXRjaFNvdXJjZSA9IChjcmVhdGVBYm9ydEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jICh1cmwpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHJldHVybiBbYXdhaXQgcmVzcG9uc2UudGV4dCgpLCByZXNwb25zZS51cmxdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH0gLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1lbXB0eVxuICAgICAgICB0aHJvdyBjcmVhdGVBYm9ydEVycm9yKCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mZXRjaC1zb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGdhaW46IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBHYWluTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUdhaW5Ob2RlLCBnYWluTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9nYWluID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUdhaW5Ob2RlLmdhaW4sIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2FpbjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2Fpbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlR2Fpbk5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVHYWluTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlR2Fpbk5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlR2Fpbk5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVHYWluTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiBuYXRpdmVHYWluTm9kZS5nYWluLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVHYWluTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlR2Fpbk5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVHYWluTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUdhaW5Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlR2Fpbk5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSAoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLCBnZXRWYWx1ZUZvcktleSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSkgPT4gZ2V0VmFsdWVGb3JLZXkoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEF1ZGlvTm9kZVJlbmRlcmVyID0gKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICBpZiAoYXVkaW9Ob2RlQ29ubmVjdGlvbnMucmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcmVuZGVyZXIgb2YgdGhlIGdpdmVuIEF1ZGlvTm9kZSBpbiB0aGUgYXVkaW8gZ3JhcGguJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF1ZGlvTm9kZUNvbm5lY3Rpb25zLnJlbmRlcmVyO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lID0gKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSkgPT4geyB2YXIgX2E7IHJldHVybiAoX2EgPSBhdWRpb05vZGVUYWlsVGltZVN0b3JlLmdldChhdWRpb05vZGUpKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAwOyB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyID0gKGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAoYXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSk7XG4gICAgICAgIGlmIChhdWRpb1BhcmFtQ29ubmVjdGlvbnMucmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcmVuZGVyZXIgb2YgdGhlIGdpdmVuIEF1ZGlvUGFyYW0gaW4gdGhlIGF1ZGlvIGdyYXBoLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhdWRpb1BhcmFtQ29ubmVjdGlvbnMucmVuZGVyZXI7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0ludmFsaWRTdGF0ZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnZhbGlkLXN0YXRlLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCBjcmVhdGVHZXROYXRpdmVDb250ZXh0ID0gKGNvbnRleHRTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoY29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgbGV0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTQxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjcmVhdGluZyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGggbGVzcyB0aGFuIDQ0MTAwIEh6LlxuICAgICAgICBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5zZXQobmF0aXZlQ29udGV4dCwgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW9yLWNyZWF0ZS1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPSAodW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPSB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgaWYgKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb250ZXh0IGhhcyBubyBzZXQgb2YgQXVkaW9Xb3JrbGV0Tm9kZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcztcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZXMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdJbnZhbGlkQWNjZXNzRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludmFsaWQtYWNjZXNzLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZCA9IChuYXRpdmVJSVJGaWx0ZXJOb2RlKSA9PiB7XG4gICAgbmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZSA9ICgoZ2V0RnJlcXVlbmN5UmVzcG9uc2UpID0+IHtcbiAgICAgICAgcmV0dXJuIChmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZ2V0RnJlcXVlbmN5UmVzcG9uc2UuY2FsbChuYXRpdmVJSVJGaWx0ZXJOb2RlLCBmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUlJUkZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtaWlyLWZpbHRlci1ub2RlLWdldC1mcmVxdWVuY3ktcmVzcG9uc2UtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtaWlyLWZpbHRlci1ub2RlLWdldC1mcmVxdWVuY3ktcmVzcG9uc2UtbWV0aG9kJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSwgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIElJUkZpbHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZShuYXRpdmVDb250ZXh0LCBpc09mZmxpbmUgPyBudWxsIDogY29udGV4dC5iYXNlTGF0ZW5jeSwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpaXJGaWx0ZXJOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlcihtZXJnZWRPcHRpb25zLmZlZWRiYWNrLCBtZXJnZWRPcHRpb25zLmZlZWRmb3J3YXJkKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVJSVJGaWx0ZXJOb2RlLCBpaXJGaWx0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICMyMyAmICMyNDogRmlyZWZveERldmVsb3BlciBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IuXG4gICAgICAgICAgICAvLyBAdG9kbyBXcml0ZSBhIHRlc3Qgd2hpY2ggYWxsb3dzIG90aGVyIGJyb3dzZXJzIHRvIHJlbWFpbiB1bnBhdGNoZWQuXG4gICAgICAgICAgICB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kKG5hdGl2ZUlJUkZpbHRlck5vZGUpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlSUlSRmlsdGVyTm9kZSA9IG5hdGl2ZUlJUkZpbHRlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUlJUkZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWlyLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsIi8vIFRoaXMgaW1wbGVtZW50YXRpb24gYXMgc2hhbWVsZXNzbHkgaW5zcGlyZWQgYnkgc291cmNlIGNvZGUgb2Zcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbi8vIHtAbGluayBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjLmdpdC8rL21hc3Rlci90aGlyZF9wYXJ0eS9XZWJLaXQvU291cmNlL3BsYXRmb3JtL2F1ZGlvL0lJUkZpbHRlci5jcHB8Q2hyb21pdW0ncyBJSVJGaWx0ZXJ9LlxuZXhwb3J0IGNvbnN0IGZpbHRlckJ1ZmZlciA9IChmZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyLCB5QnVmZmVyLCBidWZmZXJJbmRleCwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgbGV0IGkgPSBidWZmZXJJbmRleDtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgbGV0IHkgPSBmZWVkZm9yd2FyZFswXSAqIGlucHV0W2pdO1xuICAgICAgICBmb3IgKGxldCBrID0gMTsgayA8IG1pbkxlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgICAgICB5ICs9IGZlZWRmb3J3YXJkW2tdICogeEJ1ZmZlclt4XTtcbiAgICAgICAgICAgIHkgLT0gZmVlZGJhY2tba10gKiB5QnVmZmVyW3hdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGsgPSBtaW5MZW5ndGg7IGsgPCBmZWVkZm9yd2FyZExlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgICB5ICs9IGZlZWRmb3J3YXJkW2tdICogeEJ1ZmZlclsoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpXTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IG1pbkxlbmd0aDsgayA8IGZlZWRiYWNrTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIHkgLT0gZmVlZGJhY2tba10gKiB5QnVmZmVyWyhpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSldOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgfVxuICAgICAgICB4QnVmZmVyW2ldID0gaW5wdXRbal07XG4gICAgICAgIHlCdWZmZXJbaV0gPSB5O1xuICAgICAgICBpID0gKGkgKyAxKSAmIChidWZmZXJMZW5ndGggLSAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgIG91dHB1dFtqXSA9IHk7XG4gICAgfVxuICAgIHJldHVybiBpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbHRlci1idWZmZXIuanMubWFwIiwiaW1wb3J0IHsgZmlsdGVyQnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9maWx0ZXItYnVmZmVyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuY29uc3QgZmlsdGVyRnVsbEJ1ZmZlciA9IChyZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkKSA9PiB7XG4gICAgY29uc3QgY29udmVydGVkRmVlZGJhY2sgPSBmZWVkYmFjayBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRiYWNrIDogbmV3IEZsb2F0NjRBcnJheShmZWVkYmFjayk7XG4gICAgY29uc3QgY29udmVydGVkRmVlZGZvcndhcmQgPSBmZWVkZm9yd2FyZCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRmb3J3YXJkIDogbmV3IEZsb2F0NjRBcnJheShmZWVkZm9yd2FyZCk7XG4gICAgY29uc3QgZmVlZGJhY2tMZW5ndGggPSBjb252ZXJ0ZWRGZWVkYmFjay5sZW5ndGg7XG4gICAgY29uc3QgZmVlZGZvcndhcmRMZW5ndGggPSBjb252ZXJ0ZWRGZWVkZm9yd2FyZC5sZW5ndGg7XG4gICAgY29uc3QgbWluTGVuZ3RoID0gTWF0aC5taW4oZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkTGVuZ3RoKTtcbiAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gIT09IDEpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmZWVkYmFja0xlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb252ZXJ0ZWRGZWVkZm9yd2FyZFtpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRiYWNrW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGJ1ZmZlckxlbmd0aCA9IDMyO1xuICAgIGNvbnN0IHhCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgY29uc3QgeUJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICBjb25zdCBmaWx0ZXJlZEJ1ZmZlciA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMsIHJlbmRlcmVkQnVmZmVyLmxlbmd0aCwgcmVuZGVyZWRCdWZmZXIuc2FtcGxlUmF0ZSk7XG4gICAgY29uc3QgbnVtYmVyT2ZDaGFubmVscyA9IHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSByZW5kZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gZmlsdGVyZWRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgIHhCdWZmZXIuZmlsbCgwKTtcbiAgICAgICAgeUJ1ZmZlci5maWxsKDApO1xuICAgICAgICBmaWx0ZXJCdWZmZXIoY29udmVydGVkRmVlZGJhY2ssIGZlZWRiYWNrTGVuZ3RoLCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCwgZmVlZGZvcndhcmRMZW5ndGgsIG1pbkxlbmd0aCwgeEJ1ZmZlciwgeUJ1ZmZlciwgMCwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbHRlcmVkQnVmZmVyO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChmZWVkYmFjaywgZmVlZGZvcndhcmQpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICBsZXQgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlSUlSRmlsdGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVJSVJGaWx0ZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgSUlSRmlsdGVyTm9kZXMuXG4gICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFuYXRpdmVJSVJGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgZGVmaW5lcyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVJSVJGaWx0ZXIoKSBhcyBhcnJheXMgb2YgbnVtYmVycy5cbiAgICAgICAgICAgICAgICBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoZmVlZGZvcndhcmQsIGZlZWRiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsID8gbmF0aXZlSUlSRmlsdGVyTm9kZSA6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0NzogVGhlIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGluIFNhZmFyaSBnZXRzIG5vdCBpbml0aWFsaXplZCBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQuZGVzdGluYXRpb24uY2hhbm5lbENvdW50LCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5sZW5ndGgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkQnVmZmVyID0gYXdhaXQgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyRnVsbEJ1ZmZlcihyZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkKTtcbiAgICAgICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWRCdWZmZXIgPSBhd2FpdCBmaWx0ZXJlZEJ1ZmZlclByb21pc2U7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IGZpbHRlcmVkQnVmZmVyO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUlJUkZpbHRlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUlJUkZpbHRlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWlyLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkgPSAoY3ljbGVDb3VudGVycywgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGlzQWN0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChpc09mZmxpbmUpID0+IHtcbiAgICAgICAgcmV0dXJuIChhdWRpb05vZGUsIGNvdW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjeWNsZUNvdW50ZXIgPSBjeWNsZUNvdW50ZXJzLmdldChhdWRpb05vZGUpO1xuICAgICAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgaXNBY3RpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBvdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dFsxXSwgb3V0cHV0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0ob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvUGFyYW0sIG91dHB1dFsxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjb3VudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGN5Y2xlQ291bnRlciArIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluY3JlbWVudC1jeWNsZS1jb3VudGVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0ID0gKGNvbnRleHRTdG9yZSwgaXNOYXRpdmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGFueXRoaW5nKTtcbiAgICAgICAgcmV0dXJuIGlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpIHx8IGlzTmF0aXZlQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvTm9kZSA9IChhdWRpb05vZGVTdG9yZSwgaXNOYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiBhdWRpb05vZGVTdG9yZS5oYXMoYW55dGhpbmcpIHx8IGlzTmF0aXZlQXVkaW9Ob2RlKGFueXRoaW5nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb1BhcmFtID0gKGF1ZGlvUGFyYW1TdG9yZSwgaXNOYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4gYXVkaW9QYXJhbVN0b3JlLmhhcyhhbnl0aGluZykgfHwgaXNOYXRpdmVBdWRpb1BhcmFtKGFueXRoaW5nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjb250ZXh0U3RvcmUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoYW55dGhpbmcpO1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpIHx8IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dCA9IChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIGFueXRoaW5nIGluc3RhbmNlb2YgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3I7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gd2luZG93ICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3cuQXVkaW9Ob2RlID09PSAnZnVuY3Rpb24nICYmIGFueXRoaW5nIGluc3RhbmNlb2Ygd2luZG93LkF1ZGlvTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0gPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gd2luZG93ICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3cuQXVkaW9QYXJhbSA9PT0gJ2Z1bmN0aW9uJyAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIHdpbmRvdy5BdWRpb1BhcmFtO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUNvbnRleHQgPSAoaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIGlzTmF0aXZlQXVkaW9Db250ZXh0KGFueXRoaW5nKSB8fCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3I7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc1NlY3VyZUNvbnRleHQgPSAod2luZG93KSA9PiB3aW5kb3cgIT09IG51bGwgJiYgd2luZG93LmlzU2VjdXJlQ29udGV4dDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXNlY3VyZS1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTcxOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtZWRpYUVsZW1lbnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLm1lZGlhRWxlbWVudDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzM6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdHJlYW0oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZS5zdHJlYW07XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MjogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWVkaWFTdHJlYW0oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBudWxsKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IGlzVmFsaWRMYXRlbmN5SGludCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50JztcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxBdWRpb0NvbnRleHQgZXh0ZW5kcyBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTIgU2FmYXJpIGRvZXMgdGhyb3cgYSBTeW50YXhFcnJvciBpZiB0aGUgc2FtcGxlUmF0ZSBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIgJiYgZXJyLm1lc3NhZ2UgPT09ICdzYW1wbGVSYXRlIGlzIG5vdCBpbiByYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxMzEgU2FmYXJpIHJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGFyZSBmb3VyIG90aGVyIEF1ZGlvQ29udGV4dHMgcnVubmluZyBhbHJlYWR5LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVVua25vd25FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1MSBPbmx5IENocm9tZSBhbmQgRWRnZSB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gbGF0ZW5jeUhpbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHByb3ZpZGVkIHZhbHVlICcke29wdGlvbnMubGF0ZW5jeUhpbnR9JyBpcyBub3QgYSB2YWxpZCBlbnVtIHZhbHVlIG9mIHR5cGUgQXVkaW9Db250ZXh0TGF0ZW5jeUNhdGVnb3J5LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNTAgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyB0aGUgc2FtcGxlUmF0ZS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCAmJiBuYXRpdmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSAhPT0gb3B0aW9ucy5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvQ29udGV4dCwgMik7XG4gICAgICAgICAgICBjb25zdCB7IGxhdGVuY3lIaW50IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgeyBzYW1wbGVSYXRlIH0gPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBAdG9kbyBUaGUgdmFsdWVzIGZvciAnYmFsYW5jZWQnLCAnaW50ZXJhY3RpdmUnIGFuZCAncGxheWJhY2snIGFyZSBqdXN0IGNvcGllZCBmcm9tIENocm9tZSdzIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgdGhpcy5fYmFzZUxhdGVuY3kgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3kgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgID8gbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5XG4gICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gNTEyIC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAyNTYgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDEwMjQgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLypcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAdG9kbyBUaGUgbWluICgyNTYpIGFuZCBtYXggKDE2Mzg0KSB2YWx1ZXMgYXJlIHRha2VuIGZyb20gdGhlIGFsbG93ZWQgYnVmZmVyU2l6ZSB2YWx1ZXMgb2YgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFNjcmlwdFByb2Nlc3Nvck5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWF0aC5tYXgoMiwgTWF0aC5taW4oMTI4LCBNYXRoLnJvdW5kKChsYXRlbmN5SGludCAqIHNhbXBsZVJhdGUpIC8gMTI4KSkpICogMTI4KSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQgPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBCdWcgIzE4ODogU2FmYXJpIHdpbGwgc2V0IHRoZSBjb250ZXh0J3Mgc3RhdGUgdG8gJ2ludGVycnVwdGVkJyBpbiBjYXNlIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWUgPSAxZS0zNztcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5jb25uZWN0KHRoaXMuX25hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICMzNDogQ2hyb21lIGFuZCBFZGdlIHByZXRlbmQgdG8gYmUgcnVubmluZyByaWdodCBhd2F5LCBidXQgZmlyZSBhbiBvbnN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gdGhlIHN0YXRlIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgICAgICAgICAqIHRvICdydW5uaW5nJy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAnc3VzcGVuZGVkJztcbiAgICAgICAgICAgICAgICBjb25zdCByZXZva2VTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYmFzZUxhdGVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUxhdGVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlICE9PSBudWxsID8gdGhpcy5fc3RhdGUgOiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzM1OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBBdWRpb0NvbnRleHQgd2FzIGNsb3NlZCBiZWZvcmUuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzM0OiBJZiB0aGUgc3RhdGUgd2FzIHNldCB0byBzdXNwZW5kZWQgYmVmb3JlIGl0IHNob3VsZCBiZSByZXZva2VkIG5vdy5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUdhaW5Ob2RlICE9PSBudWxsICYmIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdW1lKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVQcm9taXNlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXN1bWUoKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVzdW1lKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTU6IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IgaW5zdGVhZCBvZiBhbiBJbnZhbGlkU3RhdGVFcnJvci5cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQgfHwgZXJyLmNvZGUgPT09IDE1KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN1c3BlbmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN1c3BlbmQoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW5pbWFsLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgQ09OVEVYVF9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9MaXN0ZW5lciwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dCBleHRlbmRzIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgc3VwZXIoX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dCA9IF9uYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgQ09OVEVYVF9TVE9SRS5zZXQodGhpcywgX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChfbmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLnNldChfbmF0aXZlQ29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2Rlc3RpbmF0aW9uID0gbmV3IGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IodGhpcywgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lciA9IGNyZWF0ZUF1ZGlvTGlzdGVuZXIodGhpcywgX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5fb25zdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3RpbmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25zdGF0ZWNoYW5nZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbnN0YXRlY2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbnN0YXRlY2hhbmdlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dC5vbnN0YXRlY2hhbmdlID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25TdGF0ZUNoYW5nZSA9IHRoaXMuX25hdGl2ZUNvbnRleHQub25zdGF0ZWNoYW5nZTtcbiAgICAgICAgICAgIHRoaXMuX29uc3RhdGVjaGFuZ2UgPSBuYXRpdmVPblN0YXRlQ2hhbmdlICE9PSBudWxsICYmIG5hdGl2ZU9uU3RhdGVDaGFuZ2UgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25TdGF0ZUNoYW5nZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0UHJvbWlzZVN1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIC8vIFRoaXMgMTIgbnVtYmVycyByZXByZXNlbnQgdGhlIDQ4IGJ5dGVzIG9mIGFuIGVtcHR5IFdBVkUgZmlsZSB3aXRoIGEgc2luZ2xlIHNhbXBsZS5cbiAgICBjb25zdCB1aW50MzJBcnJheSA9IG5ldyBVaW50MzJBcnJheShbMTE3OTAxMTQxMCwgNDAsIDExNjMyODA3MjcsIDU0NDUwMTA5NCwgMTYsIDEzMTA3MywgNDQxMDAsIDE3NjQwMCwgMTA0ODU4MCwgMTYzNTAxNzA2MCwgNCwgMF0pO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIEJ1ZyAjMTogU2FmYXJpIHJlcXVpcmVzIGEgc3VjY2Vzc0NhbGxiYWNrLlxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEodWludDMyQXJyYXkuYnVmZmVyLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocHJvbWlzZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgcmVqZWN0ZWQgZXJyb3JzLlxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtcHJvbWlzZS1zdXBwb3J0LmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzdGFydFJlbmRlcmluZykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyAjMjEgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgYW5kIHRoZXJlZm9yZSB3b3VsZCBmaXJlIHRoZSBzdGF0ZWNoYW5nZSBldmVudCBiZWZvcmUgdGhlIHByb21pc2UgY2FuIGJlIHJlc29sdmVkLlxuICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsICgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50ID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlbGF5U3RhdGVDaGFuZ2VFdmVudDtcbiAgICAgICAgICAgICAgICB9KSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlID09PSBudWxsID8gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGF0ZSA6IHRoaXMuX3N0YXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmVuZGVyaW5nKCkge1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOSAmICM1OTogSXQgaXMgdGhlb3JldGljYWxseSBwb3NzaWJsZSB0aGF0IHN0YXJ0UmVuZGVyaW5nKCkgd2lsbCBmaXJzdCByZW5kZXIgYSBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC4gVGhlcmVmb3JlXG4gICAgICAgICAgICAgKiB0aGUgc3RhdGUgb2YgdGhlIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgbWlnaHQgbm8gdHJhbnNpdGlvbiB0byBydW5uaW5nIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3J1bm5pbmcnO1xuICAgICAgICAgICAgcmV0dXJuIHN0YXJ0UmVuZGVyaW5nKHRoaXMuZGVzdGluYXRpb24sIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIF93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMgPSAoaW5zZXJ0RWxlbWVudEluU2V0LCBpc05hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Ob2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldCgpO1xuICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdCA9ICgoY29ubmVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZCBuby1pbmZlcnJhYmxlLXR5cGVzXG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB3YXNEaXNjb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID09PSAwO1xuICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChjb25uZWN0aW9ucywgW2Rlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0XSwgKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmIGNvbm5lY3Rpb25bMV0gPT09IG91dHB1dCAmJiBjb25uZWN0aW9uWzJdID09PSBpbnB1dCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3YXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoZW5Db25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVzdGluYXRpb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChjb25uZWN0aW9ucywgW2Rlc3RpbmF0aW9uLCBvdXRwdXRdLCAoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICBpZiAod2FzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoZW5Db25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QpO1xuICAgICAgICBuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA+IDA7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmFwcGx5KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAxIGFyZ3VtZW50IHlldC5cbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25bMV0gPT09IGRlc3RpbmF0aW9uT3JPdXRwdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAyIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uT3JPdXRwdXQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3V0cHV0ID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3Rpb25bMl0gPT09IGlucHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpc0Rpc2Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPT09IDA7XG4gICAgICAgICAgICAgICAgaWYgKHdhc0Nvbm5lY3RlZCAmJiBpc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB3aGVuRGlzY29ubmVjdGVkKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bW9uaXRvci1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uID0gKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgb3B0aW9uKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW29wdGlvbl07XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG5hdGl2ZUF1ZGlvTm9kZVtvcHRpb25dKSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZVtvcHRpb25dID0gdmFsdWU7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24uanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zID0gKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucykgPT4ge1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsQ291bnQnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCAnY2hhbm5lbENvdW50TW9kZScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsSW50ZXJwcmV0YXRpb24nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0ID0gKG5hdGl2ZUFuYWx5c2VyTm9kZSkgPT4ge1xuICAgIHJldHVybiB0eXBlb2YgbmF0aXZlQW5hbHlzZXJOb2RlLmdldEZsb2F0VGltZURvbWFpbkRhdGEgPT09ICdmdW5jdGlvbic7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZCA9IChuYXRpdmVBbmFseXNlck5vZGUpID0+IHtcbiAgICBuYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSA9IChhcnJheSkgPT4ge1xuICAgICAgICBjb25zdCBieXRlVGltZURvbWFpbkRhdGEgPSBuZXcgVWludDhBcnJheShhcnJheS5sZW5ndGgpO1xuICAgICAgICBuYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGJ5dGVUaW1lRG9tYWluRGF0YSk7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWF4KGJ5dGVUaW1lRG9tYWluRGF0YS5sZW5ndGgsIG5hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgYXJyYXlbaV0gPSAoYnl0ZVRpbWVEb21haW5EYXRhW2ldIC0gMTI4KSAqIDAuMDA3ODEyNTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyYXk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyB3cmFwQW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeSA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgICAgLy8gQnVnICMzNzogRmlyZWZveCBkb2VzIG5vdCBjcmVhdGUgYW4gQW5hbHlzZXJOb2RlIHdpdGggdGhlIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBCdWcgIzExODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIG1heERlY2liZWxzIGlzIG5vdCBtb3JlIHRoYW4gbWluRGVjaWJlbHMuXG4gICAgICAgIGlmICghKG9wdGlvbnMubWF4RGVjaWJlbHMgPiBvcHRpb25zLm1pbkRlY2liZWxzKSkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnZmZ0U2l6ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnbWF4RGVjaWJlbHMnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ21pbkRlY2liZWxzJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdzbW9vdGhpbmdUaW1lQ29uc3RhbnQnKTtcbiAgICAgICAgLy8gQnVnICMzNjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSgpIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0LCAoKSA9PiB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQobmF0aXZlQW5hbHlzZXJOb2RlKSkpIHtcbiAgICAgICAgICAgIHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kKG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hdGl2ZUFuYWx5c2VyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9CdWZmZXInKSkge1xuICAgICAgICByZXR1cm4gd2luZG93LkF1ZGlvQnVmZmVyO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCBhdWRpb1BhcmFtKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW2F1ZGlvUGFyYW1dO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBuYXRpdmVBdWRpb05vZGVbYXVkaW9QYXJhbV0udmFsdWUpIHtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlW2F1ZGlvUGFyYW1dLnZhbHVlID0gdmFsdWU7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZS5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzID0gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgbGV0IGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNTY2hlZHVsZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgaXNTY2hlZHVsZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCh0eXBlb2YgZHVyYXRpb24gPT09ICdudW1iZXInICYmIGR1cmF0aW9uIDwgMCkgfHwgb2Zmc2V0IDwgMCB8fCB3aGVuIDwgMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHBhcmFtZXRlcnMgY2FuJ3QgYmUgbmVnYXRpdmUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdGFydCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wID0gKChzdG9wKSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDApID0+IHtcbiAgICAgICAgICAgIGlmICh3aGVuIDwgMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHBhcmFtZXRlciBjYW4ndCBiZSBuZWdhdGl2ZS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdG9wLmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxscyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBsaW5nLCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlciwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ3BsYXliYWNrUmF0ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnYnVmZmVyJyk7XG4gICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcEVuZCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcFN0YXJ0Jyk7XG4gICAgICAgIC8vIEJ1ZyAjNjk6IFNhZmFyaSBkb2VzIGFsbG93IGNhbGxzIHRvIHN0YXJ0KCkgb2YgYW4gYWxyZWFkeSBzY2hlZHVsZWQgQXVkaW9CdWZmZXJTb3VyY2VOb2RlLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNTQgJiAjMTU1OiBTYWZhcmkgZG9lcyBub3QgaGFuZGxlIG9mZnNldHMgd2hpY2ggYXJlIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGxpbmcobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE2MjogU2FmYXJpIGRvZXMgdGhyb3cgYW4gZXJyb3Igd2hlbiBzdG9wKCkgaXMgY2FsbGVkIG9uIGFuIEF1ZGlvQnVmZmVyU291cmNlTm9kZSB3aGljaCBoYXMgbm8gYnVmZmVyIGFzc2lnbmVkIHRvIGl0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogU2FmYXJpIGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE5OiBTYWZhcmkgZG9lcyBub3QgaWdub3JlIGNhbGxzIHRvIHN0b3AoKSBvZiBhbiBhbHJlYWR5IHN0b3BwZWQgQXVkaW9CdWZmZXJTb3VyY2VOb2RlLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIEF1ZGlvQnVmZmVyU291cmNlTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb0NvbnRleHQnKSkge1xuICAgICAgICByZXR1cm4gd2luZG93LkF1ZGlvQ29udGV4dDtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnd2Via2l0QXVkaW9Db250ZXh0JykgPyB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0IDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgLy8gQnVnICMxMzI6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudC5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCAhPT0gY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE2OTogU2FmYXJpIHRocm93cyBhbiBlcnJvciBvbiBlYWNoIGF0dGVtcHQgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM4MzogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50TW9kZS5cbiAgICAgICAgaWYgKGlzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCAmJiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlICE9PSAnZXhwbGljaXQnKSB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0JztcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGRvZXMgbm90IGluaXRpYWxpemUgdGhlIG1heENoYW5uZWxDb3VudCBwcm9wZXJ0eSBjb3JyZWN0bHkuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgJ21heENoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogY2hhbm5lbENvdW50XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE2ODogTm8gYnJvd3NlciBkb2VzIHlldCBoYXZlIGFuIEF1ZGlvRGVzdGluYXRpb25Ob2RlIHdpdGggYW4gb3V0cHV0LlxuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxDb3VudCcsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE2OTogU2FmYXJpIHRocm93cyBhbiBlcnJvciBvbiBlYWNoIGF0dGVtcHQgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoZ2Fpbk5vZGUsICdjaGFubmVsQ291bnRNb2RlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoZ2Fpbk5vZGUsICdjaGFubmVsSW50ZXJwcmV0YXRpb24nLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdhaW5Ob2RlLCAnbWF4Q2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEB0b2RvIFRoaXMgc2hvdWxkIGJlIGRpc2Nvbm5lY3RlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGNsb3NlZC5cbiAgICAgICAgZ2Fpbk5vZGUuY29ubmVjdChuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIHJldHVybiBnYWluTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9Xb3JrbGV0Tm9kZScpID8gd2luZG93LkF1ZGlvV29ya2xldE5vZGUgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtY2xvbmFiaWxpdHktb2YtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hbWUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlQ29udGV4dCwgbmFtZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgICAgIGxldCBvbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCB7XG4gICAgICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjE6IE92ZXJ3cml0aW5nIHRoZSBwcm9wZXJ0eSBhY2Nlc3NvcnMgZm9yIGNoYW5uZWxDb3VudCBhbmQgY2hhbm5lbENvdW50TW9kZSBpcyBuZWNlc3NhcnkgYXMgbG9uZyBhcyBzb21lXG4gICAgICAgICAgICAgICAgICAgICAqIGJyb3dzZXJzIGhhdmUgbm8gbmF0aXZlIGltcGxlbWVudGF0aW9uIHRvIGFjaGlldmUgYSBjb25zaXN0ZW50IGJlaGF2aW9yLlxuICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNTY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgeWV0IGZpcmUgYW4gRXJyb3JFdmVudC5cbiAgICAgICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBvbnByb2Nlc3NvcmVycm9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5hZGRFdmVudExpc3RlbmVyID0gKChhZGRFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09ICdwcm9jZXNzb3JlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnBhdGNoZWRFdmVudExpc3RlbmVyID0gdHlwZW9mIGFyZ3NbMV0gPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIGFyZ3NbMV0gPT09ICdvYmplY3QnICYmIGFyZ3NbMV0gIT09IG51bGwgJiYgdHlwZW9mIGFyZ3NbMV0uaGFuZGxlRXZlbnQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1sxXS5oYW5kbGVFdmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bnBhdGNoZWRFdmVudExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhldmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogeyB2YWx1ZTogJ3Byb2Nlc3NvcmVycm9yJyB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhdGNoZWRFdmVudExpc3RlbmVyKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIobmV3IEVycm9yRXZlbnQoYXJnc1swXSwgeyAuLi5ldmVudCB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5zZXQodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciwgYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAnZXJyb3InLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgLi4uYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5hZGRFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSAoKHJlbW92ZUV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ3Byb2Nlc3NvcmVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzg6IENocm9tZSBhbmQgRWRnZSBkbyBmaXJlIGFuIGV2ZW50IG9mIHR5cGUgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgJ2Vycm9yJywgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzg2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGludm9rZSB0aGUgcHJvY2VzcygpIGZ1bmN0aW9uIGlmIHRoZSBjb3JyZXNwb25kaW5nIEF1ZGlvV29ya2xldE5vZGUgaXMgdW5jb25uZWN0ZWQgYnV0XG4gICAgICAgICAgICAgICAgICogaGFzIGFuIG91dHB1dC5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4gbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gbmF0aXZlR2Fpbk5vZGUuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gRGlzY29ubmVjdCB0aGUgY29ubmVjdGlvbiB3aGVuIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gb2YgdGhlIEF1ZGlvV29ya2xldE5vZGUgcmV0dXJucyBmYWxzZS5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MDogQ2hyb21lICYgRWRnZSB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciBpbnN0ZWFkIG9mIGEgTm90U3VwcG9ydGVkRXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM2MTogT25seSBDaHJvbWUgJiBFZGdlIGhhdmUgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIEF1ZGlvV29ya2xldE5vZGUgeWV0LlxuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNvbXB1dGVCdWZmZXJTaXplID0gKGJhc2VMYXRlbmN5LCBzYW1wbGVSYXRlKSA9PiB7XG4gICAgaWYgKGJhc2VMYXRlbmN5ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiA1MTI7XG4gICAgfVxuICAgIHJldHVybiBNYXRoLm1heCg1MTIsIE1hdGgubWluKDE2Mzg0LCBNYXRoLnBvdygyLCBNYXRoLnJvdW5kKE1hdGgubG9nMihiYXNlTGF0ZW5jeSAqIHNhbXBsZVJhdGUpKSkpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb21wdXRlLWJ1ZmZlci1zaXplLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjbG9uZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBwb3J0MS5vbm1lc3NhZ2UgPSAoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgICAgcG9ydDEub25tZXNzYWdlZXJyb3IgPSAoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVqZWN0KGRhdGEpO1xuICAgICAgICB9O1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQyLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBjbG9uZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi9jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSA9IGFzeW5jIChwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBjbG9uZWRBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IGF3YWl0IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIHJldHVybiBuZXcgcHJvY2Vzc29yQ29uc3RydWN0b3IoY2xvbmVkQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wcm9taXNlLmpzLm1hcCIsImltcG9ydCB7IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgfSBmcm9tICcuL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wcm9taXNlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgbGV0IG5vZGVUb1Byb2Nlc3Nvck1hcCA9IE5PREVfVE9fUFJPQ0VTU09SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgIGlmIChub2RlVG9Qcm9jZXNzb3JNYXAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBub2RlVG9Qcm9jZXNzb3JNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBOT0RFX1RPX1BST0NFU1NPUl9NQVBTLnNldChuYXRpdmVDb250ZXh0LCBub2RlVG9Qcm9jZXNzb3JNYXApO1xuICAgIH1cbiAgICBjb25zdCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZShwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIG5vZGVUb1Byb2Nlc3Nvck1hcC5zZXQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSk7XG4gICAgcmV0dXJuIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjb21wdXRlQnVmZmVyU2l6ZSB9IGZyb20gJy4uL2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZSc7XG5pbXBvcnQgeyBjb3B5RnJvbUNoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktZnJvbS1jaGFubmVsJztcbmltcG9ydCB7IGNvcHlUb0NoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktdG8tY2hhbm5lbCc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBjcmVhdGVOZXN0ZWRBcnJheXMgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZS1uZXN0ZWQtYXJyYXlzJztcbmltcG9ydCB7IFJlYWRPbmx5TWFwIH0gZnJvbSAnLi4vcmVhZC1vbmx5LW1hcCc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeSA9IChjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mSW5wdXRzID09PSAwICYmIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxDb3VudCA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpXG4gICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICA6IEFycmF5LmZyb20ob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpO1xuICAgICAgICAvLyBAdG9kbyBDaGVjayBpZiBhbnkgb2YgdGhlIGNoYW5uZWxDb3VudCB2YWx1ZXMgaXMgZ3JlYXRlciB0aGFuIHRoZSBpbXBsZW1lbnRhdGlvbidzIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzLlxuICAgICAgICBpZiAob3V0cHV0Q2hhbm5lbENvdW50LnNvbWUoKGNoYW5uZWxDb3VudCkgPT4gY2hhbm5lbENvdW50IDwgMSkpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dENoYW5uZWxDb3VudC5sZW5ndGggIT09IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gb3B0aW9ucy5jaGFubmVsQ291bnQgKiBvcHRpb25zLm51bWJlck9mSW5wdXRzO1xuICAgICAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgICAgICBjb25zdCBudW1iZXJPZlBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkID8gMCA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmxlbmd0aDtcbiAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgaWYgKG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycyA+IDYgfHwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA+IDYpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWVzc2FnZUNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgY29uc3QgZ2Fpbk5vZGVzID0gW107XG4gICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGdhaW5Ob2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGVzID0gW107XG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgZGVmYXVsdFZhbHVlLCBtYXhWYWx1ZSwgbWluVmFsdWUsIG5hbWUgfSBvZiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMucGFyYW1ldGVyRGF0YVtuYW1lXSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG9wdGlvbnMucGFyYW1ldGVyRGF0YVtuYW1lXVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWUgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gKGRlZmF1bHRWYWx1ZSA9PT0gdW5kZWZpbmVkID8gMCA6IGRlZmF1bHRWYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbWF4VmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gKG1heFZhbHVlID09PSB1bmRlZmluZWQgPyBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCA6IG1heFZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBtaW5WYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAobWluVmFsdWUgPT09IHVuZGVmaW5lZCA/IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUIDogbWluVmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGVzLnB1c2goY29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnMpXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY29tcHV0ZUJ1ZmZlclNpemUoYmFzZUxhdGVuY3ksIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycywgXG4gICAgICAgIC8vIEJ1ZyAjODc6IE9ubHkgRmlyZWZveCB3aWxsIGZpcmUgYW4gQXVkaW9Qcm9jZXNzaW5nRXZlbnQgaWYgdGhlcmUgaXMgbm8gY29ubmVjdGVkIG91dHB1dC5cbiAgICAgICAgTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscykpO1xuICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscylcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG91dHB1dENoYW5uZWxDb3VudFtpXVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICBnYWluTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldKTtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCBqLCBpICogb3B0aW9ucy5jaGFubmVsQ291bnQgKyBqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJhbWV0ZXJNYXAgPSBuZXcgUmVhZE9ubHlNYXAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5tYXAoKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNvbnN0YW50U291cmNlTm9kZXNbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIDAsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtuYW1lLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0XTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICBsZXQgY2hhbm5lbEludGVycHJldGF0aW9uID0gb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIGxldCBvbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgLy8gQnVnICM4NzogRXhwb3NlIGF0IGxlYXN0IG9uZSBvdXRwdXQgdG8gbWFrZSB0aGlzIG5vZGUgY29ubmVjdGFibGUuXG4gICAgICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZXMgPSBvcHRpb25zLm51bWJlck9mT3V0cHV0cyA9PT0gMCA/IFtzY3JpcHRQcm9jZXNzb3JOb2RlXSA6IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcztcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclNpemU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudChfKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUoXykge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZ2Fpbk5vZGUgb2YgZ2Fpbk5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlcztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9ucHJvY2Vzc29yZXJyb3IoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9ucHJvY2Vzc29yZXJyb3I7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG9ucHJvY2Vzc29yZXJyb3IodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3IgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlci5hZGRFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFyYW1ldGVycygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyYW1ldGVyTWFwO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3J0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlQ2hhbm5lbC5wb3J0MjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbm5lY3Q6IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRBdWRpb05vZGVzKSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3Q6IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRBdWRpb05vZGVzKSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5hZGRFdmVudExpc3RlbmVyID0gKChhZGRFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHR5cGVvZiBhcmdzWzFdID09PSAnb2JqZWN0JyAmJiBhcmdzWzFdICE9PSBudWxsICYmIHR5cGVvZiBhcmdzWzFdLmhhbmRsZUV2ZW50ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdLmhhbmRsZUV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKG5hdGl2ZUNvbnRleHQuY3VycmVudFRpbWUsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihldmVudCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLnNldCh1bnBhdGNoZWRFdmVudExpc3RlbmVyLCBhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG1lc3NhZ2VDaGFubmVsLnBvcnQxLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyID0gKChyZW1vdmVFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5kZWxldGUoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChtZXNzYWdlQ2hhbm5lbC5wb3J0MSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyKTtcbiAgICAgICAgbGV0IG9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlQ2hhbm5lbC5wb3J0MSwgJ29ubWVzc2FnZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gb25tZXNzYWdlLFxuICAgICAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ubWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb25tZXNzYWdlID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5zdGFydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnByb3RvdHlwZS5wb3J0ID0gbWVzc2FnZUNoYW5uZWwucG9ydDE7XG4gICAgICAgIGxldCBhdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSBudWxsO1xuICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpO1xuICAgICAgICBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlLnRoZW4oKGRXcmtsdFByY3NzcikgPT4gKGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGRXcmtsdFByY3NzcikpO1xuICAgICAgICBjb25zdCBpbnB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZklucHV0cywgb3B0aW9ucy5jaGFubmVsQ291bnQpO1xuICAgICAgICBjb25zdCBvdXRwdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzLCBvdXRwdXRDaGFubmVsQ291bnQpO1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5yZWR1Y2UoKHBybXRycywgeyBuYW1lIH0pID0+ICh7IC4uLnBybXRycywgW25hbWVdOiBuZXcgRmxvYXQzMkFycmF5KDEyOCkgfSksIHt9KTtcbiAgICAgICAgbGV0IGlzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdE91dHB1dHNHcmFwaCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyA+IDApIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBqLCBqKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0SW5kZXhlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciwgb3V0cHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgIGlmIChhdWRpb1dvcmtsZXRQcm9jZXNzb3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dHMgPSBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlcik7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXJTaXplOyBpICs9IDEyOCkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKGlucHV0QnVmZmVyLCBpbnB1dHNbal0sIGssIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5mb3JFYWNoKCh7IG5hbWUgfSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwoaW5wdXRCdWZmZXIsIHBhcmFtZXRlcnMsIG5hbWUsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4LCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3V0cHV0c1tqXVtrXS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dHNbal1ba10gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3RlbnRpYWxseUVtcHR5SW5wdXRzID0gaW5wdXRzLm1hcCgoaW5wdXQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aXZlSW5wdXQgPSBhY3RpdmVJbnB1dHNbaW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY3RpdmVJbnB1dC5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJbnB1dEluZGV4ZXMuc2V0KGluZGV4LCBidWZmZXJTaXplIC8gMTI4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3VudCA9IGFjdGl2ZUlucHV0SW5kZXhlcy5nZXQoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0LmV2ZXJ5KChjaGFubmVsRGF0YSkgPT4gY2hhbm5lbERhdGEuZXZlcnkoKHNhbXBsZSkgPT4gc2FtcGxlID09PSAwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJbnB1dEluZGV4ZXMuZGVsZXRlKGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5zZXQoaW5kZXgsIGNvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVTb3VyY2VGbGFnID0gZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSArIGkgLyBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yLnByb2Nlc3MocG90ZW50aWFsbHlFbXB0eUlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNBY3RpdmUgPSBhY3RpdmVTb3VyY2VGbGFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weVRvQ2hhbm5lbChvdXRwdXRCdWZmZXIsIG91dHB1dHNbal0sIGssIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBrLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbal07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLmRpc3BhdGNoRXZlbnQobmV3IEVycm9yRXZlbnQoJ3Byb2Nlc3NvcmVycm9yJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5vOiBlcnJvci5jb2xubyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogZXJyb3IuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZW5vOiBlcnJvci5saW5lbm8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzW2pdLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tqXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0uZGlzY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCBrLCBqICogb3B0aW9ucy5jaGFubmVsQ291bnQgKyBrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNvbnN0YW50U291cmNlTm9kZXNbal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIDAsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbE1lcmdlck5vZGUuZGlzY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSBudWxsOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0T3V0cHV0c0dyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIC8vIEJ1ZyAjODc6IE9ubHkgRmlyZWZveCB3aWxsIGZpcmUgYW4gQXVkaW9Qcm9jZXNzaW5nRXZlbnQgaWYgdGhlcmUgaXMgbm8gY29ubmVjdGVkIG91dHB1dC5cbiAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY29ubmVjdEZha2VHcmFwaCA9ICgpID0+IHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdEZha2VHcmFwaCA9ICgpID0+IHtcbiAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0T3V0cHV0c0dyYXBoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdRJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdkZXR1bmUnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2ZyZXF1ZW5jeScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZ2FpbicpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAndHlwZScpO1xuICAgIHJldHVybiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1iaXF1YWQtZmlsdGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeSA9IChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgd3JhcENoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDaGFubmVsTWVyZ2VyKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMpO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzIwOiBTYWZhcmkgcmVxdWlyZXMgYSBjb25uZWN0aW9uIG9mIGFueSBraW5kIHRvIHRyZWF0IHRoZSBpbnB1dCBzaWduYWwgY29ycmVjdGx5LlxuICAgICAgICAgKiBAdG9kbyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIHdheSB0byB0ZXN0IGZvciB0aGlzIGJlaGF2aW9yIGluIGEgc3luY2hyb25vdXMgZmFzaGlvbiB3aGljaCBpcyB3aHkgdGVzdGluZyBmb3IgdGhlIGV4aXN0ZW5jZSBvZlxuICAgICAgICAgKiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgIHdyYXBDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW52YWxpZC1zdGF0ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUgPSAoY2hhbm5lbFNwbGl0dGVyTm9kZSkgPT4ge1xuICAgIGNvbnN0IGNoYW5uZWxDb3VudCA9IGNoYW5uZWxTcGxpdHRlck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgIC8vIEJ1ZyAjOTc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQgdG8gc29tZXRoaW5nIG90aGVyIHRoYW4gaXRzIGluaXRpYWwgdmFsdWUuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxTcGxpdHRlck5vZGUsICdjaGFubmVsQ291bnQnLCB7XG4gICAgICAgIGdldDogKCkgPT4gY2hhbm5lbENvdW50LFxuICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gQnVnICMzMDogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudE1vZGUgdG8gc29tZXRoaW5nIG90aGVyIHRoYW4gZXhwbGljaXQuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxTcGxpdHRlck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywge1xuICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gQnVnICMzMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxJbnRlcnByZXRhdGlvbiB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBkaXNjcmV0ZS5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiAnZGlzY3JldGUnLFxuICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSAnZGlzY3JldGUnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBDaGFubmVsU3BsaXR0ZXJOb2RlIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWNoYW5uZWwtc3BsaXR0ZXItbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzKTtcbiAgICAvLyBCdWcgIzk2OiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnQuXG4gICAgLy8gQnVnICMyOTogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50TW9kZS5cbiAgICAvLyBCdWcgIzMxOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsSW50ZXJwcmV0YXRpb24uXG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICAvLyBCdWcgIzI5LCAjMzAsICMzMSwgIzMyLCAjOTYgJiAjOTc6IE9ubHkgQ2hyb21lLCBFZGdlICYgRmlyZWZveCBwYXJ0aWFsbHkgc3VwcG9ydCB0aGUgc3BlYyB5ZXQuXG4gICAgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgcmV0dXJuIG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBCdWcgIzYyOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIG9wdGlvbnMsICdvZmZzZXQnKTtcbiAgICAgICAgLy8gQnVnICM0NDogU2FmYXJpIGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQ29uc3RhbnRTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaW50ZXJjZXB0Q29ubmVjdGlvbnMgPSAob3JpZ2luYWwsIGludGVyY2VwdG9yKSA9PiB7XG4gICAgb3JpZ2luYWwuY29ubmVjdCA9IGludGVyY2VwdG9yLmNvbm5lY3QuYmluZChpbnRlcmNlcHRvcik7XG4gICAgb3JpZ2luYWwuZGlzY29ubmVjdCA9IGludGVyY2VwdG9yLmRpc2Nvbm5lY3QuYmluZChpbnRlcmNlcHRvcik7XG4gICAgcmV0dXJuIG9yaWdpbmFsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludGVyY2VwdC1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlckZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IG9mZnNldCwgLi4uYXVkaW9Ob2RlT3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiBvZmZzZXQgfSk7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgLy8gQnVnICM5NTogU2FmYXJpIGRvZXMgbm90IHBsYXkgb3IgbG9vcCBvbmUgc2FtcGxlIGJ1ZmZlcnMuXG4gICAgICAgIGNoYW5uZWxEYXRhWzBdID0gMTtcbiAgICAgICAgY2hhbm5lbERhdGFbMV0gPSAxO1xuICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gYXVkaW9CdWZmZXI7XG4gICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0LmNhbGwoYXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AuY2FsbChhdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QoZ2Fpbk5vZGUpO1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoZ2Fpbk5vZGUpO1xuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIEF1ZGlvQnVmZmVyU291cmNlTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyLCBnYWluTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNvbnZvbHZlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBUaGUgbm9ybWFsaXplIHByb3BlcnR5IG5lZWRzIHRvIGJlIHNldCBiZWZvcmUgc2V0dGluZyB0aGUgYnVmZmVyLlxuICAgICAgICBpZiAob3B0aW9ucy5kaXNhYmxlTm9ybWFsaXphdGlvbiA9PT0gbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUpIHtcbiAgICAgICAgICAgIG5hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplID0gIW9wdGlvbnMuZGlzYWJsZU5vcm1hbGl6YXRpb247XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUNvbnZvbHZlck5vZGUsIG9wdGlvbnMsICdidWZmZXInKTtcbiAgICAgICAgLy8gQnVnICMxMTM6IFNhZmFyaSBkb2VzIGFsbG93IHRvIHNldCB0aGUgY2hhbm5lbENvdW50IHRvIGEgdmFsdWUgbGFyZ2VyIHRoYW4gMi5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQ29udm9sdmVyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUsIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE0OiBTYWZhcmkgYWxsb3dzIHRvIHNldCB0aGUgY2hhbm5lbENvdW50TW9kZSB0byAnbWF4Jy5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUNvbnZvbHZlck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29udm9sdmVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlRGVsYXlOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVEZWxheU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZURlbGF5KG9wdGlvbnMubWF4RGVsYXlUaW1lKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZURlbGF5Tm9kZSwgb3B0aW9ucyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZURlbGF5Tm9kZSwgb3B0aW9ucywgJ2RlbGF5VGltZScpO1xuICAgIHJldHVybiBuYXRpdmVEZWxheU5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWRlbGF5LW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBCdWcgIzEwODogU2FmYXJpIGFsbG93cyBhIGNoYW5uZWxDb3VudCBvZiB0aHJlZSBhbmQgYWJvdmUuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDk6IE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IGRpc2FsbG93IGEgY2hhbm5lbENvdW50TW9kZSBvZiAnbWF4Jy5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdhdHRhY2snKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdrbmVlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAncmF0aW8nKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdyZWxlYXNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAndGhyZXNob2xkJyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVHYWluTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUdhaW5Ob2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlR2Fpbk5vZGUsIG9wdGlvbnMsICdnYWluJyk7XG4gICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1nYWluLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG9wdGlvbnMpID0+IHtcbiAgICAgICAgLy8gQnVnICM5OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBJSVJGaWx0ZXJOb2Rlcy5cbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQuY3JlYXRlSUlSRmlsdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgZGVmaW5lcyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVJSVJGaWx0ZXIoKSBhcyBhcnJheXMgb2YgbnVtYmVycy5cbiAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKG9wdGlvbnMuZmVlZGZvcndhcmQsIG9wdGlvbnMuZmVlZGJhY2spO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUlJUkZpbHRlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBjb21wdXRlQnVmZmVyU2l6ZSB9IGZyb20gJy4uL2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZSc7XG5pbXBvcnQgeyBmaWx0ZXJCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbHRlci1idWZmZXInO1xuaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5mdW5jdGlvbiBkaXZpZGUoYSwgYikge1xuICAgIGNvbnN0IGRlbm9taW5hdG9yID0gYlswXSAqIGJbMF0gKyBiWzFdICogYlsxXTtcbiAgICByZXR1cm4gWyhhWzBdICogYlswXSArIGFbMV0gKiBiWzFdKSAvIGRlbm9taW5hdG9yLCAoYVsxXSAqIGJbMF0gLSBhWzBdICogYlsxXSkgLyBkZW5vbWluYXRvcl07XG59XG5mdW5jdGlvbiBtdWx0aXBseShhLCBiKSB7XG4gICAgcmV0dXJuIFthWzBdICogYlswXSAtIGFbMV0gKiBiWzFdLCBhWzBdICogYlsxXSArIGFbMV0gKiBiWzBdXTtcbn1cbmZ1bmN0aW9uIGV2YWx1YXRlUG9seW5vbWlhbChjb2VmZmljaWVudCwgeikge1xuICAgIGxldCByZXN1bHQgPSBbMCwgMF07XG4gICAgZm9yIChsZXQgaSA9IGNvZWZmaWNpZW50Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICAgIHJlc3VsdCA9IG11bHRpcGx5KHJlc3VsdCwgeik7XG4gICAgICAgIHJlc3VsdFswXSArPSBjb2VmZmljaWVudFtpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgeyBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIGNoYW5uZWxJbnRlcnByZXRhdGlvbiwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkIH0pID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IGNvbXB1dGVCdWZmZXJTaXplKGJhc2VMYXRlbmN5LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGZWVkYmFjayA9IGZlZWRiYWNrIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGJhY2sgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRiYWNrKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkRmVlZGZvcndhcmQgPSBmZWVkZm9yd2FyZCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRmb3J3YXJkIDogbmV3IEZsb2F0NjRBcnJheShmZWVkZm9yd2FyZCk7XG4gICAgICAgIGNvbnN0IGZlZWRiYWNrTGVuZ3RoID0gY29udmVydGVkRmVlZGJhY2subGVuZ3RoO1xuICAgICAgICBjb25zdCBmZWVkZm9yd2FyZExlbmd0aCA9IGNvbnZlcnRlZEZlZWRmb3J3YXJkLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbWluTGVuZ3RoID0gTWF0aC5taW4oZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkTGVuZ3RoKTtcbiAgICAgICAgaWYgKGZlZWRiYWNrTGVuZ3RoID09PSAwIHx8IGZlZWRiYWNrTGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRiYWNrWzBdID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmZWVkZm9yd2FyZExlbmd0aCA9PT0gMCB8fCBmZWVkZm9yd2FyZExlbmd0aCA+IDIwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkZm9yd2FyZFswXSA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gIT09IDEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmVlZGZvcndhcmRMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRmb3J3YXJkW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBmZWVkYmFja0xlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29udmVydGVkRmVlZGJhY2tbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnQpO1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSBjaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIGNvbnN0IGJ1ZmZlckxlbmd0aCA9IDMyO1xuICAgICAgICBjb25zdCBidWZmZXJJbmRleGVzID0gW107XG4gICAgICAgIGNvbnN0IHhCdWZmZXJzID0gW107XG4gICAgICAgIGNvbnN0IHlCdWZmZXJzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbENvdW50OyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ1ZmZlckluZGV4ZXMucHVzaCgwKTtcbiAgICAgICAgICAgIGNvbnN0IHhCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgICAgICAgICBjb25zdCB5QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgICAgICAgICAgeEJ1ZmZlci5maWxsKDApO1xuICAgICAgICAgICAgeUJ1ZmZlci5maWxsKDApO1xuICAgICAgICAgICAgeEJ1ZmZlcnMucHVzaCh4QnVmZmVyKTtcbiAgICAgICAgICAgIHlCdWZmZXJzLnB1c2goeUJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0QnVmZmVyID0gZXZlbnQuaW5wdXRCdWZmZXI7XG4gICAgICAgICAgICBjb25zdCBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICAgICAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gaW5wdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgICAgICAgICAgYnVmZmVySW5kZXhlc1tpXSA9IGZpbHRlckJ1ZmZlcihjb252ZXJ0ZWRGZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGNvbnZlcnRlZEZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyc1tpXSwgeUJ1ZmZlcnNbaV0sIGJ1ZmZlckluZGV4ZXNbaV0sIGJ1ZmZlckxlbmd0aCwgaW5wdXQsIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG55cXVpc3QgPSBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUgLyAyO1xuICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU2l6ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbc2NyaXB0UHJvY2Vzc29yTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIERpc3NhbGxvdyBhZGRpbmcgYW4gYXVkaW9wcm9jZXNzIGxpc3RlbmVyLlxuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gZnJlcXVlbmN5SHoubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2EgPSAtTWF0aC5QSSAqIChmcmVxdWVuY3lIeltpXSAvIG55cXVpc3QpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB6ID0gW01hdGguY29zKG9tZWdhKSwgTWF0aC5zaW4ob21lZ2EpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJhdG9yID0gZXZhbHVhdGVQb2x5bm9taWFsKGNvbnZlcnRlZEZlZWRmb3J3YXJkLCB6KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVub21pbmF0b3IgPSBldmFsdWF0ZVBvbHlub21pYWwoY29udmVydGVkRmVlZGJhY2ssIHopO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGRpdmlkZShudW1lcmF0b3IsIGRlbm9taW5hdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgbWFnUmVzcG9uc2VbaV0gPSBNYXRoLnNxcnQocmVzcG9uc2VbMF0gKiByZXNwb25zZVswXSArIHJlc3BvbnNlWzFdICogcmVzcG9uc2VbMV0pO1xuICAgICAgICAgICAgICAgICAgICBwaGFzZVJlc3BvbnNlW2ldID0gTWF0aC5hdGFuMihyZXNwb25zZVsxXSwgcmVzcG9uc2VbMF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyLCBzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKG9wdGlvbnMubWVkaWFFbGVtZW50KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIG9wdGlvbnMpO1xuICAgIC8vIEJ1ZyAjMTc0OiBTYWZhcmkgZG9lcyBleHBvc2UgYSB3cm9uZyBudW1iZXJPZk91dHB1dHMuXG4gICAgaWYgKG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUubnVtYmVyT2ZPdXRwdXRzID09PSAxKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCAnbnVtYmVyT2ZPdXRwdXRzJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCB7IG1lZGlhU3RyZWFtIH0pID0+IHtcbiAgICBjb25zdCBhdWRpb1N0cmVhbVRyYWNrcyA9IG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCk7XG4gICAgLypcbiAgICAgKiBCdWcgIzE1MTogU2FmYXJpIGRvZXMgbm90IHVzZSB0aGUgYXVkaW8gdHJhY2sgYXMgaW5wdXQgYW55bW9yZSBpZiBpdCBnZXRzIHJlbW92ZWQgZnJvbSB0aGUgbWVkaWFTdHJlYW0gYWZ0ZXIgY29uc3RydWN0aW9uLlxuICAgICAqIEJ1ZyAjMTU5OiBTYWZhcmkgcGlja3MgdGhlIGZpcnN0IGF1ZGlvIHRyYWNrIGlmIHRoZSBNZWRpYVN0cmVhbSBoYXMgbW9yZSB0aGFuIG9uZSBhdWRpbyB0cmFjay5cbiAgICAgKi9cbiAgICBhdWRpb1N0cmVhbVRyYWNrcy5zb3J0KChhLCBiKSA9PiAoYS5pZCA8IGIuaWQgPyAtMSA6IGEuaWQgPiBiLmlkID8gMSA6IDApKTtcbiAgICBjb25zdCBmaWx0ZXJlZEF1ZGlvU3RyZWFtVHJhY2tzID0gYXVkaW9TdHJlYW1UcmFja3Muc2xpY2UoMCwgMSk7XG4gICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobmV3IE1lZGlhU3RyZWFtKGZpbHRlcmVkQXVkaW9TdHJlYW1UcmFja3MpKTtcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTUxICYgIzE1OTogVGhlIGdpdmVuIG1lZGlhU3RyZWFtIGdldHMgcmVjb25zdHJ1Y3RlZCBiZWZvcmUgaXQgZ2V0cyBwYXNzZWQgdG8gdGhlIG5hdGl2ZSBub2RlIHdoaWNoIGlzIHdoeSB0aGUgYWNjZXNzb3IgbmVlZHNcbiAgICAgKiB0byBiZSBvdmVyd3JpdHRlbiBhcyBpdCB3b3VsZCBvdGhlcndpc2UgZXhwb3NlIHRoZSByZWNvbnN0cnVjdGVkIHZlcnNpb24uXG4gICAgICovXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCAnbWVkaWFTdHJlYW0nLCB7IHZhbHVlOiBtZWRpYVN0cmVhbSB9KTtcbiAgICByZXR1cm4gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Db250ZXh0LCB7IG1lZGlhU3RyZWFtVHJhY2sgfSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzEyMTogT25seSBGaXJlZm94IGRvZXMgeWV0IHN1cHBvcnQgdGhlIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUuXG4gICAgICAgIGlmICh0eXBlb2YgbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZShtZWRpYVN0cmVhbVRyYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbShbbWVkaWFTdHJlYW1UcmFja10pO1xuICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShtZWRpYVN0cmVhbSk7XG4gICAgICAgIC8vIEJ1ZyAjMTIwOiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBtZWRpYVN0cmVhbSBoYXMgbm8gYXVkaW8gdHJhY2suXG4gICAgICAgIGlmIChtZWRpYVN0cmVhbVRyYWNrLmtpbmQgIT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzI6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUF1ZGlvQ29udGV4dCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdPZmZsaW5lQXVkaW9Db250ZXh0JykpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5PZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0JykgPyB3aW5kb3cud2Via2l0T2ZmbGluZUF1ZGlvQ29udGV4dCA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ2RldHVuZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMsICdmcmVxdWVuY3knKTtcbiAgICAgICAgaWYgKG9wdGlvbnMucGVyaW9kaWNXYXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnNldFBlcmlvZGljV2F2ZShvcHRpb25zLnBlcmlvZGljV2F2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMsICd0eXBlJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBDaHJvbWUgJiBFZGdlIHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTk6IFNhZmFyaSBkb2VzIG5vdCBpZ25vcmUgY2FsbHMgdG8gc3RvcCgpIG9mIGFuIGFscmVhZHkgc3RvcHBlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlT3NjaWxsYXRvck5vZGUsIG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIE9zY2lsbGF0b3JOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW9zY2lsbGF0b3Itbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBCdWcgIzEyNDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZ5aW5nIHRoZSBvcmllbnRhdGlvbiBhbmQgdGhlIHBvc2l0aW9uIHdpdGggQXVkaW9QYXJhbXMuXG4gICAgICAgIGlmIChuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25YJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25ZJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25aJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25YJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25ZJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25aJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZUlubmVyQW5nbGUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lT3V0ZXJBbmdsZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVPdXRlckdhaW4nKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdkaXN0YW5jZU1vZGVsJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnbWF4RGlzdGFuY2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwYW5uaW5nTW9kZWwnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdyZWZEaXN0YW5jZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3JvbGxvZmZGYWN0b3InKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0Rmlyc3RTYW1wbGUsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBjb25lSW5uZXJBbmdsZSwgY29uZU91dGVyQW5nbGUsIGNvbmVPdXRlckdhaW4sIGRpc3RhbmNlTW9kZWwsIG1heERpc3RhbmNlLCBvcmllbnRhdGlvblgsIG9yaWVudGF0aW9uWSwgb3JpZW50YXRpb25aLCBwYW5uaW5nTW9kZWwsIHBvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblosIHJlZkRpc3RhbmNlLCByb2xsb2ZmRmFjdG9yLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgcGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMTI1OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICBpZiAoYXVkaW9Ob2RlT3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTI2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICBpZiAoYXVkaW9Ob2RlT3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKHBhbm5lck5vZGUsIGF1ZGlvTm9kZU9wdGlvbnMpO1xuICAgICAgICBjb25zdCBTSU5HTEVfQ0hBTk5FTF9PUFRJT05TID0ge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJ1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBudW1iZXJPZklucHV0czogNlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25YR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvblpHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25YR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvblpHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgMjU2LCA2LCAxKTtcbiAgICAgICAgY29uc3Qgd2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IG5ldyBGbG9hdDMyQXJyYXkoWzEsIDFdKSxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6ICdub25lJ1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFtvcmllbnRhdGlvblgsIG9yaWVudGF0aW9uWSwgb3JpZW50YXRpb25aXTtcbiAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFtwb3NpdGlvblgsIHBvc2l0aW9uWSwgcG9zaXRpb25aXTtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheSgxKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAwKSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAxKSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAyKVxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0T3JpZW50YXRpb24oLi4ub3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW1xuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDMpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDQpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDUpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnNldFBvc2l0aW9uKC4uLnBvc2l0b24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9yaWVudGF0aW9uWUdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9yaWVudGF0aW9uWkdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWEdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWUdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWkdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZUlubmVyQW5nbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29uZUlubmVyQW5nbGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNvbmVJbm5lckFuZ2xlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVPdXRlckdhaW4oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29uZU91dGVyR2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZU91dGVyR2Fpbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZU91dGVyR2FpbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubWF4RGlzdGFuY2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG1heERpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLm1heERpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWEdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25ZR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvblpHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYW5uaW5nTW9kZWwoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUucGFubmluZ01vZGVsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBwYW5uaW5nTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWEdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25ZR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblpHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5yZWZEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgcmVmRGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyOTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucmVmRGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcm9sbG9mZkZhY3RvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMzA6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGNvbmVJbm5lckFuZ2xlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZUlubmVyQW5nbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lSW5uZXJBbmdsZSA9IGNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25lT3V0ZXJBbmdsZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckFuZ2xlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyQW5nbGUgPSBjb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZU91dGVyR2FpbiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckdhaW4pIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJHYWluID0gY29uZU91dGVyR2FpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzdGFuY2VNb2RlbCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmRpc3RhbmNlTW9kZWwpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5kaXN0YW5jZU1vZGVsID0gZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF4RGlzdGFuY2UgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5tYXhEaXN0YW5jZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm1heERpc3RhbmNlID0gbWF4RGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWC52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWC52YWx1ZSA9IG9yaWVudGF0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25ZICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25ZLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25ZLnZhbHVlID0gb3JpZW50YXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblogIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvbloudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvbloudmFsdWUgPSBvcmllbnRhdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhbm5pbmdNb2RlbCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBhbm5pbmdNb2RlbCkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBhbm5pbmdNb2RlbCA9IHBhbm5pbmdNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25YICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25YLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25YLnZhbHVlID0gcG9zaXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblkgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblkudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblkudmFsdWUgPSBwb3NpdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWi52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWi52YWx1ZSA9IHBvc2l0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVmRGlzdGFuY2UgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yZWZEaXN0YW5jZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnJlZkRpc3RhbmNlID0gcmVmRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJvbGxvZmZGYWN0b3IgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yb2xsb2ZmRmFjdG9yKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucm9sbG9mZkZhY3RvciA9IHJvbGxvZmZGYWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhc3RPcmllbnRhdGlvblswXSAhPT0gMSB8fCBsYXN0T3JpZW50YXRpb25bMV0gIT09IDAgfHwgbGFzdE9yaWVudGF0aW9uWzJdICE9PSAwKSB7XG4gICAgICAgICAgICBwYW5uZXJOb2RlLnNldE9yaWVudGF0aW9uKC4uLmxhc3RPcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdFBvc2l0aW9uWzBdICE9PSAwIHx8IGxhc3RQb3NpdGlvblsxXSAhPT0gMCB8fCBsYXN0UG9zaXRpb25bMl0gIT09IDApIHtcbiAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0UG9zaXRpb24oLi4ubGFzdFBvc2l0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFubmVyTm9kZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKGlucHV0R2Fpbk5vZGUsIHdhdmVTaGFwZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25YR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvbllHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWkdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAyKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25YR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDMpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvbllHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgNCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWkdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCA1KTtcbiAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShpbnB1dEdhaW5Ob2RlLCB3YXZlU2hhcGVyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvbllHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvbllHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25aR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25aR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvbllHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvbllHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25aR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25aR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5kaXNjb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVBhbm5lck5vZGVGYWtlciwgcGFubmVyTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZUZhY3RvcnkgPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgZGlzYWJsZU5vcm1hbGl6YXRpb24sIGltYWcsIHJlYWwgfSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE4MDogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHVzZSBvcmRpbmFyeSBhcnJheXMuXG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEltYWcgPSBpbWFnIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gaW1hZyA6IG5ldyBGbG9hdDMyQXJyYXkoaW1hZyk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZFJlYWwgPSByZWFsIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gcmVhbCA6IG5ldyBGbG9hdDMyQXJyYXkocmVhbCk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVBlcmlvZGljV2F2ZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKGNvbnZlcnRlZFJlYWwsIGNvbnZlcnRlZEltYWcsIHsgZGlzYWJsZU5vcm1hbGl6YXRpb24gfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTgxOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW5kZXhTaXplRXJyb3Igc28gZmFyIGlmIHRoZSBnaXZlbiBhcnJheXMgaGF2ZSBsZXNzIHRoYW4gdHdvIHZhbHVlcy5cbiAgICAgICAgaWYgKEFycmF5LmZyb20oaW1hZykubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlUGVyaW9kaWNXYXZlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXBlcmlvZGljLXdhdmUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSA9IChuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbm5lbENvdW50TW9kZSA9IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIG9mICdjbGFtcGVkLW1heCcgc2hvdWxkIGJlIHN1cHBvcnRlZC4gSG93ZXZlciBpdCBpcyBub3QgcG9zc2libGUgdG8gd3JpdGUgYSBwb2x5ZmlsbCBmb3IgU2FmYXJpXG4gICAgICAgICAqIHdoaWNoIHN1cHBvcnRzIGl0IGFuZCB0aGVyZWZvcmUgaXQgY2FuJ3QgYmUgc3VwcG9ydGVkIGF0IGFsbC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChjaGFubmVsQ291bnRNb2RlID09PSAnY2xhbXBlZC1tYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTA1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0aGUgU3RlcmVvUGFubmVyTm9kZS5cbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBvcHRpb25zLCAncGFuJyk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBvZiAnY2xhbXBlZC1tYXgnIHNob3VsZCBiZSBzdXBwb3J0ZWQuIEhvd2V2ZXIgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHdyaXRlIGEgcG9seWZpbGwgZm9yIFNhZmFyaVxuICAgICAgICAgKiB3aGljaCBzdXBwb3J0cyBpdCBhbmQgdGhlcmVmb3JlIGl0IGNhbid0IGJlIHN1cHBvcnRlZCBhdCBhbGwuXG4gICAgICAgICAqL1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gY2hhbm5lbENvdW50TW9kZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIC8vIFRoZSBjdXJ2ZSBoYXMgYSBzaXplIG9mIDE0Yml0IHBsdXMgMSB2YWx1ZSB0byBoYXZlIGFuIGV4YWN0IHJlcHJlc2VudGF0aW9uIGZvciB6ZXJvLiBUaGlzIHZhbHVlIGhhcyBiZWVuIGRldGVybWluZWQgZXhwZXJpbWVudGFsbHkuXG4gICAgY29uc3QgQ1VSVkVfU0laRSA9IDE2Mzg1O1xuICAgIGNvbnN0IERDX0NVUlZFID0gbmV3IEZsb2F0MzJBcnJheShbMSwgMV0pO1xuICAgIGNvbnN0IEhBTEZfUEkgPSBNYXRoLlBJIC8gMjtcbiAgICBjb25zdCBTSU5HTEVfQ0hBTk5FTF9PUFRJT05TID0geyBjaGFubmVsQ291bnQ6IDEsIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyB9O1xuICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMgPSB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIG92ZXJzYW1wbGU6ICdub25lJyB9O1xuICAgIGNvbnN0IGJ1aWxkSW50ZXJuYWxHcmFwaEZvck1vbm8gPSAobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCByaWdodFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQ1VSVkVfU0laRTsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gKGkgLyAoQ1VSVkVfU0laRSAtIDEpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5jb3MoeCk7XG4gICAgICAgICAgICByaWdodFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguc2luKHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxlZnRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdFdhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IGxlZnRXYXZlU2hhcGVyQ3VydmUgfSkpO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBwYW5XYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiBEQ19DVVJWRSB9KSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHJpZ2h0V2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogcmlnaHRXYXZlU2hhcGVyQ3VydmUgfSkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChsZWZ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocmlnaHRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBsZWZ0V2F2ZVNoYXBlck5vZGUgOiBsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyByaWdodFdhdmVTaGFwZXJOb2RlIDogcmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KGxlZnRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGxlZnRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IGxlZnRXYXZlU2hhcGVyTm9kZSA6IGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHJpZ2h0V2F2ZVNoYXBlck5vZGUgOiByaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QobGVmdEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoRm9yU3RlcmVvID0gKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IGNlbnRlckluZGV4ID0gTWF0aC5mbG9vcihDVVJWRV9TSVpFIC8gMik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQ1VSVkVfU0laRTsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAoaSA+IGNlbnRlckluZGV4KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeCA9ICgoaSAtIGNlbnRlckluZGV4KSAvIChDVVJWRV9TSVpFIC0gMSAtIGNlbnRlckluZGV4KSkgKiBIQUxGX1BJO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguc2luKHgpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMDtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeCA9IChpIC8gKENVUlZFX1NJWkUgLSAxIC0gY2VudGVySW5kZXgpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDE7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAwO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5jb3MoeCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogMlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBwYW5XYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiBEQ19DVVJWRSB9KSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5jb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGNvbnN0IGJ1aWxkSW50ZXJuYWxHcmFwaCA9IChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50ID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRJbnRlcm5hbEdyYXBoRm9yTW9ubyhuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFubmVsQ291bnQgPT09IDIpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZEludGVybmFsR3JhcGhGb3JTdGVyZW8obmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgIH07XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgcGFuLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uYXVkaW9Ob2RlT3B0aW9ucyxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBudW1iZXJPZklucHV0czogMlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBwYW5HYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiBwYW5cbiAgICAgICAgfSk7XG4gICAgICAgIGxldCB7IGNvbm5lY3RHcmFwaCwgZGlzY29ubmVjdEdyYXBoIH0gPSBidWlsZEludGVybmFsR3JhcGgobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFuR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFuR2Fpbk5vZGUuZ2FpbiwgJ21heFZhbHVlJywgeyBnZXQ6ICgpID0+IDEgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnbWluVmFsdWUnLCB7IGdldDogKCkgPT4gLTEgfSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKHsgY29ubmVjdEdyYXBoLCBkaXNjb25uZWN0R3JhcGggfSA9IGJ1aWxkSW50ZXJuYWxHcmFwaChuYXRpdmVDb250ZXh0LCB2YWx1ZSwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnY2xhbXBlZC1tYXgnIHx8IHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFuR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5LCBjaGFubmVsTWVyZ2VyTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgY29ycmVjdGx5IG1hcCB0aGUgdmFsdWVzLlxuICAgICAgICAgKiBAdG9kbyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIHdheSB0byB0ZXN0IGZvciB0aGlzIGJlaGF2aW9yIGluIGEgc3luY2hyb25vdXMgZmFzaGlvbiB3aGljaCBpcyB3aHkgdGVzdGluZyBmb3IgdGhlIGV4aXN0ZW5jZSBvZlxuICAgICAgICAgKiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuIFRlc3RpbmcgZm9yIHRoZSBhdXRvbWF0aW9uUmF0ZSBwcm9wZXJ0eSBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGlzIHdvcmthcm91bmRcbiAgICAgICAgICogaXNuJ3QgbmVjZXNzYXJ5IGFueW1vcmUgc2luY2UgdjE0LjAuMiBvZiBTYWZhcmkuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiZcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnICYmXG4gICAgICAgICAgICBuYXRpdmVDb250ZXh0LmNyZWF0ZUdhaW4oKS5nYWluLmF1dG9tYXRpb25SYXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBjdXJ2ZSA9IG9wdGlvbnMuY3VydmUgPT09IG51bGwgfHwgb3B0aW9ucy5jdXJ2ZSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IG9wdGlvbnMuY3VydmUgOiBuZXcgRmxvYXQzMkFycmF5KG9wdGlvbnMuY3VydmUpO1xuICAgICAgICAvLyBCdWcgIzEwNDogQ2hyb21lIGFuZCBFZGdlIHdpbGwgdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgIGlmIChjdXJ2ZSAhPT0gbnVsbCAmJiBjdXJ2ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE9ubHkgdmFsdWVzIG9mIHR5cGUgRmxvYXQzMkFycmF5IGNhbiBiZSBhc3NpZ25lZCB0byB0aGUgY3VydmUgcHJvcGVydHkuXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVXYXZlU2hhcGVyTm9kZSwgeyBjdXJ2ZSB9LCAnY3VydmUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBvcHRpb25zLCAnb3ZlcnNhbXBsZScpO1xuICAgICAgICBsZXQgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsICdjdXJ2ZScsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKG5hdGl2ZVdhdmVTaGFwZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChuYXRpdmVXYXZlU2hhcGVyTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRENDdXJ2ZSh2YWx1ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWlzRENDdXJ2ZSh2YWx1ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlKSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGN1cnZlLCBvdmVyc2FtcGxlLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICBjb25zdCBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IGludmVydEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAtMSB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IHJldmVydEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAtMSB9KTtcbiAgICAgICAgbGV0IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IHVubW9kaWZpZWRDdXJ2ZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICByZXZlcnRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICByZXZlcnRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bm1vZGlmaWVkQ3VydmU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGN1cnZlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDI6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnZlTGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWdhdGl2ZUN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShjdXJ2ZUxlbmd0aCArIDIgLSAoY3VydmVMZW5ndGggJSAyKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aXZlQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KGN1cnZlTGVuZ3RoICsgMiAtIChjdXJ2ZUxlbmd0aCAlIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVswXSA9IHZhbHVlWzBdO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZUN1cnZlWzBdID0gLXZhbHVlW2N1cnZlTGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguY2VpbCgoY3VydmVMZW5ndGggKyAxKSAvIDIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZW50ZXJJbmRleCA9IChjdXJ2ZUxlbmd0aCArIDEpIC8gMiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRoZW9yZXRpY0luZGV4ID0gKGkgLyBsZW5ndGgpICogY2VudGVySW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb3dlckluZGV4ID0gTWF0aC5mbG9vcih0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlQ3VydmVbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVtsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogdmFsdWVbbG93ZXJJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiB2YWx1ZVt1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlQ3VydmVbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gbG93ZXJJbmRleF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAtKCgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gbG93ZXJJbmRleF0pIC1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gdXBwZXJJbmRleF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVtsZW5ndGhdID0gY3VydmVMZW5ndGggJSAyID09PSAxID8gdmFsdWVbbGVuZ3RoIC0gMV0gOiAodmFsdWVbbGVuZ3RoIC0gMl0gKyB2YWx1ZVtsZW5ndGggLSAxXSkgLyAyO1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gbmVnYXRpdmVDdXJ2ZTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHBvc2l0aXZlQ3VydmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHVubW9kaWZpZWRDdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHVubW9kaWZpZWRDdXJ2ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbaW5wdXRHYWluTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG92ZXJzYW1wbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGN1cnZlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBPbmx5IHZhbHVlcyBvZiB0eXBlIEZsb2F0MzJBcnJheSBjYW4gYmUgYXNzaWduZWQgdG8gdGhlIGN1cnZlIHByb3BlcnR5LlxuICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlci5jdXJ2ZSA9IGN1cnZlIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gY3VydmUgOiBuZXcgRmxvYXQzMkFycmF5KGN1cnZlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3ZlcnNhbXBsZSAhPT0gbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlci5vdmVyc2FtcGxlKSB7XG4gICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSkuY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoaW52ZXJ0R2Fpbk5vZGUpLmNvbm5lY3QocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSkuY29ubmVjdChyZXZlcnRHYWluTm9kZSkuY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHVubW9kaWZpZWRDdXJ2ZSkpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChpbnZlcnRHYWluTm9kZSk7XG4gICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5kaXNjb25uZWN0KHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJldmVydEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmRpc2Nvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIG91dHB1dEdhaW5Ob2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdOb3RTdXBwb3J0ZWRFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm90LXN1cHBvcnRlZC1lcnJvci5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQXVkaW9HcmFwaCB9IGZyb20gJy4uL2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHN0YXJ0UmVuZGVyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE9mZmxpbmVBdWRpb0NvbnRleHQgZXh0ZW5kcyBiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihhLCBiLCBjKSB7XG4gICAgICAgICAgICBsZXQgb3B0aW9ucztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ251bWJlcicgJiYgYiAhPT0gdW5kZWZpbmVkICYmIGMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IGxlbmd0aDogYiwgbnVtYmVyT2ZDaGFubmVsczogYSwgc2FtcGxlUmF0ZTogYyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBnaXZlbiBwYXJhbWV0ZXJzIGFyZSBub3QgdmFsaWQuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyAjMjEgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgYW5kIHRoZXJlZm9yZSB3b3VsZCBmaXJlIHRoZSBzdGF0ZWNoYW5nZSBldmVudCBiZWZvcmUgdGhlIHByb21pc2UgY2FuIGJlIHJlc29sdmVkLlxuICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsICgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50ID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlbGF5U3RhdGVDaGFuZ2VFdmVudDtcbiAgICAgICAgICAgICAgICB9KSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlID09PSBudWxsID8gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGF0ZSA6IHRoaXMuX3N0YXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmVuZGVyaW5nKCkge1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOSAmICM1OTogSXQgaXMgdGhlb3JldGljYWxseSBwb3NzaWJsZSB0aGF0IHN0YXJ0UmVuZGVyaW5nKCkgd2lsbCBmaXJzdCByZW5kZXIgYSBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC4gVGhlcmVmb3JlXG4gICAgICAgICAgICAgKiB0aGUgc3RhdGUgb2YgdGhlIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgbWlnaHQgbm8gdHJhbnNpdGlvbiB0byBydW5uaW5nIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3J1bm5pbmcnO1xuICAgICAgICAgICAgcmV0dXJuIHN0YXJ0UmVuZGVyaW5nKHRoaXMuZGVzdGluYXRpb24sIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIF93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRldHVuZTogMCxcbiAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICBwZXJpb2RpY1dhdmU6IHVuZGVmaW5lZCxcbiAgICB0eXBlOiAnc2luZSdcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgT3NjaWxsYXRvck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIGNvbnN0IG55cXVpc3QgPSBjb250ZXh0LnNhbXBsZVJhdGUgLyAyO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjODE6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2RldHVuZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUsIDE1MzYwMCwgLTE1MzYwMCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc2OiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSwgbnlxdWlzdCwgLW55cXVpc3QpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IG9zY2lsbGF0b3JOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCAmJiBtZXJnZWRPcHRpb25zLnBlcmlvZGljV2F2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5wZXJpb2RpY1dhdmUgPVxuICAgICAgICAgICAgICAgICAgICBtZXJnZWRPcHRpb25zLnBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgZGV0dW5lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldHVuZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZnJlcXVlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbmVuZGVkKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0eXBlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5wZXJpb2RpY1dhdmUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9IHBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIuc3RhcnQgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIuc3RvcCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9zY2lsbGF0b3Itbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBwZXJpb2RpY1dhdmUgPSBudWxsO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZU9zY2lsbGF0b3JOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVPc2NpbGxhdG9yTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZU9zY2lsbGF0b3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGV0dW5lOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmU6IHBlcmlvZGljV2F2ZSA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHBlcmlvZGljV2F2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZU9zY2lsbGF0b3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgcGVyaW9kaWNXYXZlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RvcCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0b3AgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU9zY2lsbGF0b3JOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9zY2lsbGF0b3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGNvbmVJbm5lckFuZ2xlOiAzNjAsXG4gICAgY29uZU91dGVyQW5nbGU6IDM2MCxcbiAgICBjb25lT3V0ZXJHYWluOiAwLFxuICAgIGRpc3RhbmNlTW9kZWw6ICdpbnZlcnNlJyxcbiAgICBtYXhEaXN0YW5jZTogMTAwMDAsXG4gICAgb3JpZW50YXRpb25YOiAxLFxuICAgIG9yaWVudGF0aW9uWTogMCxcbiAgICBvcmllbnRhdGlvblo6IDAsXG4gICAgcGFubmluZ01vZGVsOiAnZXF1YWxwb3dlcicsXG4gICAgcG9zaXRpb25YOiAwLFxuICAgIHBvc2l0aW9uWTogMCxcbiAgICBwb3NpdGlvblo6IDAsXG4gICAgcmVmRGlzdGFuY2U6IDEsXG4gICAgcm9sbG9mZkZhY3RvcjogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBQYW5uZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBwYW5uZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVQYW5uZXJOb2RlLCBwYW5uZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZSA9IG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgICAgICAgICAvLyBCdWcgIzc0OiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25YID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25ZID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25aID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25YID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25YLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25ZID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25aID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZUlubmVyQW5nbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZU91dGVyQW5nbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckdhaW47XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNvbmVPdXRlckdhaW4odmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG1heERpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLm1heERpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgcGFubmluZ01vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblgoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblkoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIHNldCByZWZEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yZWZEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgcm9sbG9mZkZhY3Rvcih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCByZW5kZXJlZEJ1ZmZlclByb21pc2UgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVHYWluTm9kZSA9IG51bGw7XG4gICAgICAgICAgICBsZXQgbmF0aXZlUGFubmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICBjb25zdCBjb21tb25BdWRpb05vZGVPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb25cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgIGNvbmVJbm5lckFuZ2xlOiBuYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlLFxuICAgICAgICAgICAgICAgIGNvbmVPdXRlckFuZ2xlOiBuYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlLFxuICAgICAgICAgICAgICAgIGNvbmVPdXRlckdhaW46IG5hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbixcbiAgICAgICAgICAgICAgICBkaXN0YW5jZU1vZGVsOiBuYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwsXG4gICAgICAgICAgICAgICAgbWF4RGlzdGFuY2U6IG5hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2UsXG4gICAgICAgICAgICAgICAgcGFubmluZ01vZGVsOiBuYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCxcbiAgICAgICAgICAgICAgICByZWZEaXN0YW5jZTogbmF0aXZlUGFubmVyTm9kZS5yZWZEaXN0YW5jZSxcbiAgICAgICAgICAgICAgICByb2xsb2ZmRmFjdG9yOiBuYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3JcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlUGFubmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVQYW5uZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTI0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZnlpbmcgdGhlIG9yaWVudGF0aW9uIGFuZCB0aGUgcG9zaXRpb24gd2l0aCBBdWRpb1BhcmFtcy5cbiAgICAgICAgICAgIGlmICgnYnVmZmVyU2l6ZScgaW4gbmF0aXZlUGFubmVyTm9kZSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZVBhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWDogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblkudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvbloudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblkudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvbloudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVHYWluTm9kZSA9PT0gbnVsbCA/IG5hdGl2ZVBhbm5lck5vZGUgOiBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlR2Fpbk5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDYsIFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0Lmxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA2XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyZWRCdWZmZXJQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMgPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25YLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblosXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25YLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblpcbiAgICAgICAgICAgICAgICAgICAgICAgIF0ubWFwKGFzeW5jIChhdWRpb1BhcmFtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBpbmRleCA9PT0gMCA/IDEgOiAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNjsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlc1tpXS5jb25uZWN0KG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzW2ldLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZEJ1ZmZlciA9IGF3YWl0IHJlbmRlcmVkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBpbnB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsRGF0YXMucHVzaChyZW5kZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbY2hhbm5lbERhdGFzWzBdWzBdLCBjaGFubmVsRGF0YXNbMV1bMF0sIGNoYW5uZWxEYXRhc1syXVswXV07XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFtjaGFubmVsRGF0YXNbM11bMF0sIGNoYW5uZWxEYXRhc1s0XVswXSwgY2hhbm5lbERhdGFzWzVdWzBdXTtcbiAgICAgICAgICAgICAgICBsZXQgZ2F0ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgICAgIGxldCBwYXJ0aWFsUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBsYXN0T3JpZW50YXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbGFzdE9yaWVudGF0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblo6IGxhc3RPcmllbnRhdGlvblsyXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBsYXN0UG9zaXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbGFzdFBvc2l0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblo6IGxhc3RQb3NpdGlvblsyXVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChnYXRlR2Fpbk5vZGUpLmNvbm5lY3QocGFydGlhbFBhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsUGFubmVyTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTI4OyBpIDwgcmVuZGVyZWRCdWZmZXIubGVuZ3RoOyBpICs9IDEyOCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtjaGFubmVsRGF0YXNbMF1baV0sIGNoYW5uZWxEYXRhc1sxXVtpXSwgY2hhbm5lbERhdGFzWzJdW2ldXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRvbiA9IFtjaGFubmVsRGF0YXNbM11baV0sIGNoYW5uZWxEYXRhc1s0XVtpXSwgY2hhbm5lbERhdGFzWzVdW2ldXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IHBvc2l0b247XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGkgLyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRlR2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWDogbGFzdE9yaWVudGF0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbGFzdE9yaWVudGF0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbGFzdE9yaWVudGF0aW9uWzJdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogbGFzdFBvc2l0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbGFzdFBvc2l0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbGFzdFBvc2l0aW9uWzJdXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDEsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChnYXRlR2Fpbk5vZGUpLmNvbm5lY3QocGFydGlhbFBhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVHYWluTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblosIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblosIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblopO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlUGFubmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVBhbm5lck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVHYWluTm9kZU9yTmF0aXZlUGFubmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVHYWluTm9kZU9yTmF0aXZlUGFubmVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yID0gKGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZSwgZ2V0TmF0aXZlQ29udGV4dCwgcGVyaW9kaWNXYXZlU3RvcmUsIHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBQZXJpb2RpY1dhdmUge1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICBjb25zdCBwZXJpb2RpY1dhdmUgPSBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBwZXJpb2RpY1dhdmVTdG9yZS5hZGQocGVyaW9kaWNXYXZlKTtcbiAgICAgICAgICAgIC8vIFRoaXMgZG9lcyB2aW9sYXRlIGFsbCBnb29kIHByYXRpY2VzIGJ1dCBpdCBpcyB1c2VkIGhlcmUgdG8gc2ltcGxpZnkgdGhlIGhhbmRsaW5nIG9mIHBlcmlvZGljIHdhdmVzLlxuICAgICAgICAgICAgcmV0dXJuIHBlcmlvZGljV2F2ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHJldHVybiAoKGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGluc3RhbmNlKSA9PT0gUGVyaW9kaWNXYXZlLnByb3RvdHlwZSkgfHxcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmVTdG9yZS5oYXMoaW5zdGFuY2UpKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGVyaW9kaWMtd2F2ZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVyQXV0b21hdGlvbiA9IChnZXRBdWRpb1BhcmFtUmVuZGVyZXIsIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtUmVuZGVyZXIgPSBnZXRBdWRpb1BhcmFtUmVuZGVyZXIoYXVkaW9QYXJhbSk7XG4gICAgICAgIGF1ZGlvUGFyYW1SZW5kZXJlci5yZXBsYXkobmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgIHJldHVybiByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItYXV0b21hdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgPSAoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBpc1BhcnRPZkFDeWNsZSkgPT4ge1xuICAgIHJldHVybiBhc3luYyAoYXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChhdWRpb05vZGVDb25uZWN0aW9ucy5hY3RpdmVJbnB1dHNcbiAgICAgICAgICAgIC5tYXAoKGNvbm5lY3Rpb25zLCBpbnB1dCkgPT4gQXJyYXkuZnJvbShjb25uZWN0aW9ucykubWFwKGFzeW5jIChbc291cmNlLCBvdXRwdXRdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhdWRpb05vZGVSZW5kZXJlciA9IGdldEF1ZGlvTm9kZVJlbmRlcmVyKHNvdXJjZSk7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IGF3YWl0IGF1ZGlvTm9kZVJlbmRlcmVyLnJlbmRlcihzb3VyY2UsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBhdWRpb05vZGUuY29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSAmJiAoYXVkaW9Ob2RlICE9PSBkZXN0aW5hdGlvbiB8fCAhaXNQYXJ0T2ZBQ3ljbGUoYXVkaW9Ob2RlKSkpIHtcbiAgICAgICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKVxuICAgICAgICAgICAgLnJlZHVjZSgoYWxsUmVuZGVyaW5nUHJvbWlzZXMsIHJlbmRlcmluZ1Byb21pc2VzKSA9PiBbLi4uYWxsUmVuZGVyaW5nUHJvbWlzZXMsIC4uLnJlbmRlcmluZ1Byb21pc2VzXSwgW10pKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1pbnB1dHMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtID0gKGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMsIGlzUGFydE9mQUN5Y2xlKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShhdWRpb1BhcmFtQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzKS5tYXAoYXN5bmMgKFtzb3VyY2UsIG91dHB1dF0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvTm9kZVJlbmRlcmVyID0gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gYXdhaXQgYXVkaW9Ob2RlUmVuZGVyZXIucmVuZGVyKHNvdXJjZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5leHBvcnQgY29uc3QgY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCB0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIGlmIChjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE1ODogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhZHZhbmNlIGN1cnJlbnRUaW1lIGlmIGl0IGlzIG5vdCBhY2Nlc3NlZCB3aGlsZSByZW5kZXJpbmcgdGhlIGF1ZGlvLlxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjYWNoZVRlc3RSZXN1bHQodGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQsIHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KSkudGhlbigoaXNPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ZWQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIDUxMiwgMCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSBudWxsOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICgpID0+IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3VycmVudFRpbWU7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAvLyBCdWcgIzQ4OiBTYWZhcmkgZG9lcyBub3QgcmVuZGVyIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aG91dCBhbnkgY29ubmVjdGVkIG5vZGUuXG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lm9uY29tcGxldGUgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShldmVudC5yZW5kZXJlZEJ1ZmZlcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2Fpbk5vZGUuY29ubmVjdChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlU2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IChhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cykgPT4ge1xuICAgICAgICBhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUuc2V0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lID0gKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgdGFpbFRpbWUpID0+IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUuc2V0KGF1ZGlvTm9kZSwgdGFpbFRpbWUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcy5tYXAiLCJpbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcywgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoZGVzdGluYXRpb24pXG4gICAgICAgIC5yZW5kZXIoZGVzdGluYXRpb24sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpXG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjODYgJiAjODc6IEludm9raW5nIHRoZSByZW5kZXJlciBvZiBhbiBBdWRpb1dvcmtsZXROb2RlIG1pZ2h0IGJlIG5lY2Vzc2FyeSBpZiBpdCBoYXMgbm8gZGlyZWN0IG9yIGluZGlyZWN0IGNvbm5lY3Rpb24gdG8gdGhlXG4gICAgICAgICAqIGRlc3RpbmF0aW9uLlxuICAgICAgICAgKi9cbiAgICAgICAgLnRoZW4oKCkgPT4gUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpLm1hcCgoYXVkaW9Xb3JrbGV0Tm9kZSkgPT4gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoYXVkaW9Xb3JrbGV0Tm9kZSkucmVuZGVyKGF1ZGlvV29ya2xldE5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKSkpXG4gICAgICAgIC50aGVuKCgpID0+IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpXG4gICAgICAgIC50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NzogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0aGUgYnVmZmVyT2Zmc2V0IHRvIGJlIG91dC1vZi1ib3VuZHMuXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhcnQtcmVuZGVyaW5nLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgLypcbiAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgc2hvdWxkIGJlICdjbGFtcGVkLW1heCcgYWNjb3JkaW5nIHRvIHRoZSBzcGVjIGJ1dCBpcyBzZXQgdG8gJ2V4cGxpY2l0JyB0byBhY2hpZXZlIGNvbnNpc3RlbnRcbiAgICAgKiBiZWhhdmlvci5cbiAgICAgKi9cbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBwYW46IDBcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBTdGVyZW9QYW5uZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBzdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBzdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fcGFuID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFuKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhbjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBwYW46IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVTdGVyZW9QYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGFuLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLnBhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wYW4sIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiLy8gQnVnICMzMzogU2FmYXJpIGV4cG9zZXMgYW4gQXVkaW9CdWZmZXIgYnV0IGl0IGNhbid0IGJlIHVzZWQgYXMgYSBjb25zdHJ1Y3Rvci5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQgPSAobmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoOiAxLCBzYW1wbGVSYXRlOiA0NDEwMCB9KTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLXN1cHBvcnQuanMubWFwIiwiLy8gQnVnICMxNzk6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdG8gdHJhbnNmZXIgYW55IGJ1ZmZlciB3aGljaCBoYXMgYmVlbiBwYXNzZWQgdG8gdGhlIHByb2Nlc3MoKSBtZXRob2QgYXMgYW4gYXJndW1lbnQuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCA9IChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNjE6IElmIHRoZXJlIGlzIG5vIG5hdGl2ZSBBdWRpb1dvcmtsZXROb2RlIGl0IGdldHMgZmFrZWQgYW5kIHRoZXJlZm9yZSBpdCBpcyBubyBwcm9ibGVtIGlmIHRoZSBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFsnY2xhc3MgQSBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3Nvcntwcm9jZXNzKGkpe3RoaXMucG9ydC5wb3N0TWVzc2FnZShpLFtpWzBdWzBdLmJ1ZmZlcl0pfX1yZWdpc3RlclByb2Nlc3NvcihcImFcIixBKSddLCB7XG4gICAgICAgICAgICB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCdcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTQxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjcmVhdGluZyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGggbGVzcyB0aGFuIDQ0MTAwIEh6LlxuICAgICAgICBjb25zdCBvZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxMjgsIDQ0MTAwKTtcbiAgICAgICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgbGV0IGlzRW1pdHRpbmdNZXNzYWdlRXZlbnRzID0gZmFsc2U7XG4gICAgICAgIGxldCBpc0VtaXR0aW5nUHJvY2Vzc29yRXJyb3JFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IG9mZmxpbmVBdWRpb0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSh1cmwpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3Iob2ZmbGluZUF1ZGlvQ29udGV4dCwgJ2EnLCB7IG51bWJlck9mT3V0cHV0czogMCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG9zY2lsbGF0b3IgPSBvZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgICAgIGF1ZGlvV29ya2xldE5vZGUucG9ydC5vbm1lc3NhZ2UgPSAoKSA9PiAoaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgPSB0cnVlKTtcbiAgICAgICAgICAgIGF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9ICgpID0+IChpc0VtaXR0aW5nUHJvY2Vzc29yRXJyb3JFdmVudHMgPSB0cnVlKTtcbiAgICAgICAgICAgIG9zY2lsbGF0b3IuY29ubmVjdChhdWRpb1dvcmtsZXROb2RlKTtcbiAgICAgICAgICAgIG9zY2lsbGF0b3Iuc3RhcnQoMCk7XG4gICAgICAgICAgICBhd2FpdCBvZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgJiYgIWlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cztcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcG9zdC1tZXNzYWdlLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIC8vIEJ1ZyAjNDg6IFNhZmFyaSBkb2VzIG5vdCByZW5kZXIgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRob3V0IGFueSBjb25uZWN0ZWQgbm9kZS5cbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgeWV0LlxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmN1cnJlbnRUaW1lICE9PSAwKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY3VycmVudC10aW1lLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVVua25vd25FcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdVbmtub3duRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVua25vd24tZXJyb3IuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgY3VydmU6IG51bGwsXG4gICAgb3ZlcnNhbXBsZTogJ25vbmUnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBXYXZlU2hhcGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCB3YXZlU2hhcGVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgLy8gQHRvZG8gQWRkIGEgbWVjaGFuaXNtIHRvIG9ubHkgc3dpdGNoIGEgV2F2ZVNoYXBlck5vZGUgdG8gYWN0aXZlIHdoaWxlIGl0IGlzIGNvbm5lY3RlZC5cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB3YXZlU2hhcGVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlV2F2ZVNoYXBlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0N1cnZlTnVsbGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGN1cnZlKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzEwMzogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHNldCB0aGUgY3VydmUgdG8gbnVsbC5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShbMCwgMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDI6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTA0OiBDaHJvbWUgYW5kIEVkZ2Ugd2lsbCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9pc0N1cnZlTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvdmVyc2FtcGxlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmUtc2hhcGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlV2F2ZVNoYXBlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVXYXZlU2hhcGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlV2F2ZVNoYXBlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBjdXJ2ZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJzYW1wbGU6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlV2F2ZVNoYXBlck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVdhdmVTaGFwZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVXYXZlU2hhcGVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13YXZlLXNoYXBlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdpbmRvdyA9ICgpID0+ICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiB3aW5kb3cpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2luZG93LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgPSAoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nLCBjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID0gKGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgIGlmIChjaGFubmVsTnVtYmVyID49IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJMZW5ndGggPSBhdWRpb0J1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgZGVzdGluYXRpb25MZW5ndGggPSBkZXN0aW5hdGlvbi5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gYnVmZmVyT2Zmc2V0IDwgMCA/IC1idWZmZXJPZmZzZXQgOiAwOyBpICsgYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXJMZW5ndGggJiYgaSA8IGRlc3RpbmF0aW9uTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbltpXSA9IGNoYW5uZWxEYXRhW2kgKyBidWZmZXJPZmZzZXRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID0gKHNvdXJjZSwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICBpZiAoY2hhbm5lbE51bWJlciA+PSBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyTGVuZ3RoID0gYXVkaW9CdWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gYnVmZmVyT2Zmc2V0IDwgMCA/IC1idWZmZXJPZmZzZXQgOiAwOyBpICsgYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXJMZW5ndGggJiYgaSA8IHNvdXJjZUxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbERhdGFbaSArIGJ1ZmZlck9mZnNldF0gPSBzb3VyY2VbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMgPSAoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPSAoKGNvcHlGcm9tQ2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5RnJvbUNoYW5uZWwuY2FsbChhdWRpb0J1ZmZlciwgZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKTtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCA9ICgoY29weVRvQ2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChzb3VyY2UsIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICAgICAgaWYgKGJ1ZmZlck9mZnNldCA8IGF1ZGlvQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29weVRvQ2hhbm5lbC5jYWxsKGF1ZGlvQnVmZmVyLCBzb3VyY2UsIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlciA9IChvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBudWxsaWZpZWRCdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbnVsbGlmaWVkQnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsICdidWZmZXInLCAoZ2V0KSA9PiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGxpZmllZEJ1ZmZlciA/IG51bGwgOiB2YWx1ZTtcbiAgICAgICAgfSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB2YWx1ZSA9PT0gbnVsbCA/IG51bGxpZmllZEJ1ZmZlciA6IHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgLy8gQnVnICMxNTogU2FmYXJpIGRvZXMgbm90IHJldHVybiB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0JztcbiAgICAgICAgLy8gQnVnICMxNjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gc2V0dGluZyBhIGRpZmZlcmVudCBjaGFubmVsQ291bnQgb3IgY2hhbm5lbENvdW50TW9kZS5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxNZXJnZXJOb2RlLCAnY2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiAxLFxuICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsTWVyZ2VyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMyMDogU2FmYXJpIHJlcXVpcmVzIGEgY29ubmVjdGlvbiBvZiBhbnkga2luZCB0byB0cmVhdCB0aGUgaW5wdXQgc2lnbmFsIGNvcnJlY3RseS5cbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGNoYW5uZWxNZXJnZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IGF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgbW9uaXRvckNvbm5lY3Rpb25zKGNoYW5uZWxNZXJnZXJOb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtY2hhbm5lbC1tZXJnZXItbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgZ2V0Rmlyc3RTYW1wbGUgPSAoYXVkaW9CdWZmZXIsIGJ1ZmZlciwgY2hhbm5lbE51bWJlcikgPT4ge1xuICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICBpZiAoYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpWzBdO1xuICAgIH1cbiAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwoYnVmZmVyLCBjaGFubmVsTnVtYmVyKTtcbiAgICByZXR1cm4gYnVmZmVyWzBdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1maXJzdC1zYW1wbGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzRENDdXJ2ZSA9IChjdXJ2ZSkgPT4ge1xuICAgIGlmIChjdXJ2ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGxlbmd0aCA9IGN1cnZlLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoICUgMiAhPT0gMCkge1xuICAgICAgICByZXR1cm4gY3VydmVbTWF0aC5mbG9vcihsZW5ndGggLyAyKV0gIT09IDA7XG4gICAgfVxuICAgIHJldHVybiBjdXJ2ZVtsZW5ndGggLyAyIC0gMV0gKyBjdXJ2ZVtsZW5ndGggLyAyXSAhPT0gMDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1kYy1jdXJ2ZS5qcy5tYXAiLCJleHBvcnQgY29uc3Qgb3ZlcndyaXRlQWNjZXNzb3JzID0gKG9iamVjdCwgcHJvcGVydHksIGNyZWF0ZUdldHRlciwgY3JlYXRlU2V0dGVyKSA9PiB7XG4gICAgbGV0IHByb3RvdHlwZSA9IG9iamVjdDtcbiAgICB3aGlsZSAoIXByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgfVxuICAgIGNvbnN0IHsgZ2V0LCBzZXQgfSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocHJvdG90eXBlLCBwcm9wZXJ0eSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIHsgZ2V0OiBjcmVhdGVHZXR0ZXIoZ2V0KSwgc2V0OiBjcmVhdGVTZXR0ZXIoc2V0KSB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vdmVyd3JpdGUtYWNjZXNzb3JzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBvdXRwdXRDaGFubmVsQ291bnQ6IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50ICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgIDogb3B0aW9ucy5udW1iZXJPZklucHV0cyA9PT0gMSAmJiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyA9PT0gMVxuICAgICAgICAgICAgICAgID8gLypcbiAgICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjE6IFRoaXMgc2hvdWxkIGJlIHRoZSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMsIGJ1dCB1bmZvcnR1bmF0ZWx5IHRoYXQgaXMgYWxtb3N0IGltcG9zc2libGUgdG8gZmFrZS4gVGhhdCdzIHdoeVxuICAgICAgICAgICAgICAgICAgICogdGhlIGNoYW5uZWxDb3VudE1vZGUgaXMgcmVxdWlyZWQgdG8gYmUgJ2V4cGxpY2l0JyBhcyBsb25nIGFzIHRoZXJlIGlzIG5vdCBhIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpbiBldmVyeSBicm93c2VyLiBUaGF0XG4gICAgICAgICAgICAgICAgICAgKiBtYWtlcyBzdXJlIHRoZSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgZXF1aXZpbGFudCB0byB0aGUgY2hhbm5lbENvdW50IHdoaWNoIG1ha2VzIGl0IG11Y2ggZWFzaWVyIHRvIGNvbXB1dGUuXG4gICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgW29wdGlvbnMuY2hhbm5lbENvdW50XVxuICAgICAgICAgICAgICAgIDogQXJyYXkuZnJvbSh7IGxlbmd0aDogb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfSwgKCkgPT4gMSlcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGNoYW5uZWxDb3VudDogb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgeyBpbWFnLCByZWFsIH0gPSBvcHRpb25zO1xuICAgIGlmIChpbWFnID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHJlYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZzogWzAsIDBdLCByZWFsOiBbMCwgMF0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnOiBBcnJheS5mcm9tKHJlYWwsICgpID0+IDApLCByZWFsIH07XG4gICAgfVxuICAgIGlmIChyZWFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZywgcmVhbDogQXJyYXkuZnJvbShpbWFnLCAoKSA9PiAwKSB9O1xuICAgIH1cbiAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnLCByZWFsIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtcGVyaW9kaWMtd2F2ZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUgPSAoYXVkaW9QYXJhbSwgdmFsdWUsIHN0YXJ0VGltZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGVyci5jb2RlICE9PSA5KSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIHZhbHVlLCBzdGFydFRpbWUgKyAxZS03KTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDAsIDEpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXItc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KC0xKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgUmFuZ2VFcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKC0xKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgUmFuZ2VFcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGlmIHRoZSBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyBhcmUgbm90IGNsb25hYmxlLlxuICAgICAgICBwb3J0MS5wb3N0TWVzc2FnZShhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5LmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZyA9IChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyO1xuICAgICAgICAgICAgLy8gQnVnICMxNTQ6IFNhZmFyaSBkb2VzIG5vdCBjbGFtcCB0aGUgb2Zmc2V0IGlmIGl0IGlzIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5cbiAgICAgICAgICAgIGNvbnN0IGNsYW1wZWRPZmZzZXQgPSBidWZmZXIgPT09IG51bGwgPyBvZmZzZXQgOiBNYXRoLm1pbihidWZmZXIuZHVyYXRpb24sIG9mZnNldCk7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NTogU2FmYXJpIGRvZXMgbm90IGhhbmRsZSB0aGUgb2Zmc2V0IGNvcnJlY3RseSBpZiBpdCB3b3VsZCBjYXVzZSB0aGUgYnVmZmVyIHRvIGJlIG5vdCBiZSBwbGF5ZWQgYXQgYWxsLlxuICAgICAgICAgICAgaWYgKGJ1ZmZlciAhPT0gbnVsbCAmJiBjbGFtcGVkT2Zmc2V0ID4gYnVmZmVyLmR1cmF0aW9uIC0gMC41IC8gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbnRleHQuc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuLCAwLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuLCBjbGFtcGVkT2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICBjb25zdCBkaXNjb25uZWN0R2Fpbk5vZGUgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDEgYXJndW1lbnQgeWV0LlxuICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdEdhaW5Ob2RlKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuZGlzY29ubmVjdCk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdEdhaW5Ob2RlKTtcbiAgICBpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCA9ICgoc3RvcCkgPT4ge1xuICAgICAgICBsZXQgaXNTdG9wcGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDApID0+IHtcbiAgICAgICAgICAgIGlmIChpc1N0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBzdG9wLmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHdoZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgICAgIGlzU3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3ApO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwRXZlbnRMaXN0ZW5lciA9ICh0YXJnZXQsIGV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7IHZhbHVlOiB0YXJnZXQgfTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoZXZlbnQsIHtcbiAgICAgICAgICAgIGN1cnJlbnRUYXJnZXQ6IGRlc2NyaXB0b3IsXG4gICAgICAgICAgICB0YXJnZXQ6IGRlc2NyaXB0b3JcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlb2YgZXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50TGlzdGVuZXIuY2FsbCh0YXJnZXQsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lci5oYW5kbGVFdmVudC5jYWxsKHRhcmdldCwgZXZlbnQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1ldmVudC1saXN0ZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50IH0gZnJvbSAnYXV0b21hdGlvbi1ldmVudHMnO1xuaW1wb3J0IHsgY3JlYXRlQWJvcnRFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2Fib3J0LWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWF1ZGlvLXdvcmtsZXQtbW9kdWxlJztcbmltcG9ydCB7IGNyZWF0ZUFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24gfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtc2lsZW50LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hbmFseXNlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvTGlzdGVuZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tbGlzdGVuZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2JpcXVhZC1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ2FjaGVUZXN0UmVzdWx0IH0gZnJvbSAnLi9mYWN0b3JpZXMvY2FjaGUtdGVzdC1yZXN1bHQnO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLW1lcmdlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1zcGxpdHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0QXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2Nvbm5lY3QtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlQ29ubmVjdE11bHRpcGxlT3V0cHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdGVkLW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29udmVydC1udW1iZXItdG8tdW5zaWduZWQtbG9uZyc7XG5pbXBvcnQgeyBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvY3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlRGF0YUNsb25lRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9kYXRhLWNsb25lLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZURlY29kZUF1ZGlvRGF0YSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlY29kZS1hdWRpby1kYXRhJztcbmltcG9ydCB7IGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlciB9IGZyb20gJy4vZmFjdG9yaWVzL2RlY3JlbWVudC1jeWNsZS1jb3VudGVyJztcbmltcG9ydCB7IGNyZWF0ZURlbGF5Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsYXktbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVEZWxheU5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxheS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVEZXRlY3RDeWNsZXMgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZXRlY3QtY3ljbGVzJztcbmltcG9ydCB7IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVFbmNvZGluZ0Vycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZW5jb2RpbmctZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlRXZhbHVhdGVTb3VyY2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9ldmFsdWF0ZS1zb3VyY2UnO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2V2ZW50LXRhcmdldC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSB9IGZyb20gJy4vZmFjdG9yaWVzL2V4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlRmV0Y2hTb3VyY2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9mZXRjaC1zb3VyY2UnO1xuaW1wb3J0IHsgY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2dhaW4tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVHYWluTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2dhaW4tbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb05vZGVUYWlsVGltZSB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXRhaWwtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtbmF0aXZlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LW9yLWNyZWF0ZS1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZXMnO1xuaW1wb3J0IHsgY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaWlyLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvaW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVJbmRleFNpemVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2luZGV4LXNpemUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW52YWxpZC1hY2Nlc3MtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNTZWN1cmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtc2VjdXJlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNTdXBwb3J0ZWRQcm9taXNlIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtc3VwcG9ydGVkLXByb21pc2UnO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21pbmltYWwtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL21vbml0b3ItY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1tZXJnZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1kZWxheS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWdhaW4tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW9zY2lsbGF0b3Itbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc2NyaXB0LXByb2Nlc3Nvci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9ub3Qtc3VwcG9ydGVkLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL29mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlUGFubmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvcGFubmVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL3Bhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24gfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItYXV0b21hdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvc2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzJztcbmltcG9ydCB7IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvc2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nIH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RhcnQtcmVuZGVyaW5nJztcbmltcG9ydCB7IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3N0ZXJlby1wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNTdWJhcnJheVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1zdWJhcnJheS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRDbG9zZU1ldGhvZFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtY2xvc2UtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dERlY29kZUF1ZGlvRGF0YU1ldGhvZFR5cGVFcnJvclN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtZGVjb2RlLWF1ZGlvLWRhdGEtbWV0aG9kLXR5cGUtZXJyb3Itc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0T3B0aW9uc1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtb3B0aW9ucy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb05vZGVDb25uZWN0TWV0aG9kU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tbm9kZS1jb25uZWN0LW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JOb091dHB1dHNTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1uby1vdXRwdXRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcG9zdC1tZXNzYWdlLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENoYW5uZWxNZXJnZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY2hhbm5lbC1tZXJnZXItbm9kZS1jaGFubmVsLWNvdW50LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENvbnN0YW50U291cmNlTm9kZUFjY3VyYXRlU2NoZWR1bGluZ1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnN0YW50LXNvdXJjZS1ub2RlLWFjY3VyYXRlLXNjaGVkdWxpbmctc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUJ1ZmZlclJlYXNzaWduYWJpbGl0eVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnZvbHZlci1ub2RlLWJ1ZmZlci1yZWFzc2lnbmFiaWxpdHktc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnZvbHZlci1ub2RlLWNoYW5uZWwtY291bnQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0SXNTZWN1cmVDb250ZXh0U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtaXMtc2VjdXJlLWNvbnRleHQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0TWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVNZWRpYVN0cmVhbVdpdGhvdXRBdWRpb1RyYWNrU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLW1lZGlhLXN0cmVhbS13aXRob3V0LWF1ZGlvLXRyYWNrLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0U3RlcmVvUGFubmVyTm9kZURlZmF1bHRWYWx1ZVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LXN0ZXJlby1wYW5uZXItbm9kZS1kZWZhdWx0LXZhbHVlLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVW5rbm93bkVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvdW5rbm93bi1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVXYXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVXaW5kb3cgfSBmcm9tICcuL2ZhY3Rvcmllcy93aW5kb3cnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlcic7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWNoYW5uZWwtbWVyZ2VyLW5vZGUnO1xuaW1wb3J0IHsgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSwgQVVESU9fTk9ERV9TVE9SRSwgQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUsIEFVRElPX1BBUkFNX1NUT1JFLCBDT05URVhUX1NUT1JFLCBDWUNMRV9DT1VOVEVSUyB9IGZyb20gJy4vZ2xvYmFscyc7XG5pbXBvcnQgeyBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRGaXJzdFNhbXBsZSB9IGZyb20gJy4vaGVscGVycy9nZXQtZmlyc3Qtc2FtcGxlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9oZWxwZXJzL2dldC12YWx1ZS1mb3Ita2V5JztcbmltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaGVscGVycy9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNEQ0N1cnZlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLWRjLWN1cnZlJztcbmltcG9ydCB7IGlzUGFydE9mQUN5Y2xlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZSc7XG5pbXBvcnQgeyBpc1Bhc3NpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtcGFzc2l2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IG92ZXJ3cml0ZUFjY2Vzc29ycyB9IGZyb20gJy4vaGVscGVycy9vdmVyd3JpdGUtYWNjZXNzb3JzJztcbmltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vaGVscGVycy9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuaW1wb3J0IHsgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvc2FuaXRpemUtY2hhbm5lbC1zcGxpdHRlci1vcHRpb25zJztcbmltcG9ydCB7IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlIH0gZnJvbSAnLi9oZWxwZXJzL3NldC12YWx1ZS1hdC10aW1lLXVudGlsLXBvc3NpYmxlJztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmctc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5JztcbmltcG9ydCB7IHRlc3REb21FeGNlcHRpb25Db25zdHJ1Y3RvclN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1kb20tZXhjZXB0aW9uLWNvbnN0cnVjdG9yLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RUcmFuc2ZlcmFibGVzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LXRyYW5zZmVyYWJsZXMtc3VwcG9ydCc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZyB9IGZyb20gJy4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyB9IGZyb20gJy4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscyc7XG5pbXBvcnQgeyB3cmFwRXZlbnRMaXN0ZW5lciB9IGZyb20gJy4vaGVscGVycy93cmFwLWV2ZW50LWxpc3RlbmVyJztcbi8qXG4gKiBAdG9kbyBFeHBsaWNpdGx5IHJlZmVyZW5jaW5nIHRoZSBiYXJyZWwgZmlsZSBzZWVtcyB0byBiZSBuZWNlc3Nhcnkgd2hlbiBlbmFibGluZyB0aGVcbiAqIGlzb2xhdGVkTW9kdWxlcyBjb21waWxlciBvcHRpb24uXG4gKi9cbmV4cG9ydCAqIGZyb20gJy4vaW50ZXJmYWNlcy9pbmRleCc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzL2luZGV4JztcbmNvbnN0IGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoaW5zZXJ0RWxlbWVudEluU2V0KTtcbmNvbnN0IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShpbnNlcnRFbGVtZW50SW5TZXQpO1xuY29uc3QgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwaWNrRWxlbWVudEZyb21TZXQpO1xuY29uc3QgYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRBdWRpb05vZGVUYWlsVGltZSA9IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpO1xuY29uc3QgY2FjaGVUZXN0UmVzdWx0ID0gY3JlYXRlQ2FjaGVUZXN0UmVzdWx0KG5ldyBNYXAoKSwgbmV3IFdlYWtNYXAoKSk7XG5jb25zdCB3aW5kb3cgPSBjcmVhdGVXaW5kb3coKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZUZhY3RvcnkoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBnZXRBdWRpb05vZGVSZW5kZXJlciA9IGNyZWF0ZUdldEF1ZGlvTm9kZVJlbmRlcmVyKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKTtcbmNvbnN0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlID0gY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb05vZGUoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBpc1BhcnRPZkFDeWNsZSk7XG5jb25zdCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZ2V0TmF0aXZlQ29udGV4dCA9IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQoQ09OVEVYVF9TVE9SRSk7XG5jb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3QgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgPSBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yKHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGlzTmF0aXZlQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3QgaXNOYXRpdmVBdWRpb05vZGUgPSBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSh3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVBdWRpb1BhcmFtID0gY3JlYXRlSXNOYXRpdmVBdWRpb1BhcmFtKHdpbmRvdyk7XG5jb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGF1ZGlvTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9Ob2RlQ29uc3RydWN0b3IoY3JlYXRlQWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMoQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSksIGNyZWF0ZUFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVRhaWxUaW1lLCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIGluc2VydEVsZW1lbnRJblNldCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzUGFydE9mQUN5Y2xlLCBpc1Bhc3NpdmVBdWRpb05vZGUpLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkoQ1lDTEVfQ09VTlRFUlMsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBpc0FjdGl2ZUF1ZGlvTm9kZSksIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVEZWNyZW1lbnRDeWNsZUNvdW50ZXIoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBDWUNMRV9DT1VOVEVSUywgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCksIGNyZWF0ZURldGVjdEN5Y2xlcyhhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRWYWx1ZUZvcktleSksIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVBdWRpb1BhcmFtLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcik7XG5jb25zdCBhbmFseXNlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCB7IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yIGFzIEFuYWx5c2VyTm9kZSB9O1xuY29uc3QgYXVkaW9CdWZmZXJTdG9yZSA9IG5ldyBXZWFrU2V0KCk7XG5jb25zdCBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgY29udmVydE51bWJlclRvVW5zaWduZWRMb25nID0gY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nKG5ldyBVaW50MzJBcnJheSgxKSk7XG5jb25zdCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgPSBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nLCBjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyA9IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyk7XG5jb25zdCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvcihhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKSwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyk7XG5leHBvcnQgeyBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yIGFzIEF1ZGlvQnVmZmVyIH07XG5jb25zdCBhZGRTaWxlbnRDb25uZWN0aW9uID0gY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbihjcmVhdGVOYXRpdmVHYWluTm9kZSk7XG5jb25zdCByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gPSBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgaXNQYXJ0T2ZBQ3ljbGUpO1xuY29uc3QgY29ubmVjdEF1ZGlvUGFyYW0gPSBjcmVhdGVDb25uZWN0QXVkaW9QYXJhbShyZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZywgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIob3ZlcndyaXRlQWNjZXNzb3JzKSwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKTtcbmNvbnN0IHJlbmRlckF1dG9tYXRpb24gPSBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uKGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlcihnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMpLCByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pO1xuY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgPSBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjcmVhdGVBdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkoY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zKEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFKSwgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBBVURJT19QQVJBTV9TVE9SRSwgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyLCBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50LCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKTtcbmNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKTtcbmV4cG9ydCB7IGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIEF1ZGlvQnVmZmVyU291cmNlTm9kZSB9O1xuY29uc3QgYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBvdmVyd3JpdGVBY2Nlc3NvcnMpLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgc2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSBjcmVhdGVTZXRBdWRpb05vZGVUYWlsVGltZShhdWRpb05vZGVUYWlsVGltZVN0b3JlKTtcbmNvbnN0IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgbW9uaXRvckNvbm5lY3Rpb25zID0gY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zKGluc2VydEVsZW1lbnRJblNldCwgaXNOYXRpdmVBdWRpb05vZGUpO1xuY29uc3Qgd3JhcENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlV3JhcENoYW5uZWxNZXJnZXJOb2RlKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZUZhY3RvcnkobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHdyYXBDaGFubmVsTWVyZ2VyTm9kZSk7XG5jb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyLCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQpO1xuY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUgPSBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeShjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlciA9IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGRlbGF5Tm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciA9IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIgPSBjcmVhdGVHYWluTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZ2Fpbk5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUdhaW5Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyRmFjdG9yeShjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcik7XG5jb25zdCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydChjcmVhdGVOYXRpdmVHYWluTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSk7XG5jb25zdCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIpO1xuY29uc3QgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlLCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlQXVkaW9MaXN0ZW5lciA9IGNyZWF0ZUF1ZGlvTGlzdGVuZXJGYWN0b3J5KGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXRGaXJzdFNhbXBsZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0xpc3RlbmVyLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUsIHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpO1xuY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlT3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFjdG9yeShjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucywgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5KGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0Rmlyc3RTYW1wbGUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKTtcbmNvbnN0IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciA9IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgcGFubmVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlUGFubmVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlID0gY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeShjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBwZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciA9IGNyZWF0ZVBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yKGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZSwgZ2V0TmF0aXZlQ29udGV4dCwgbmV3IFdlYWtTZXQoKSwgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKTtcbmNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5KG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnksIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciA9IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBpc1NlY3VyZUNvbnRleHQgPSBjcmVhdGVJc1NlY3VyZUNvbnRleHQod2luZG93KTtcbmNvbnN0IGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lID0gY3JlYXRlRXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUod2luZG93KTtcbmNvbnN0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuLy8gVGhlIGFkZEF1ZGlvV29ya2xldE1vZHVsZSgpIGZ1bmN0aW9uIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgU2VjdXJlQ29udGV4dC5cbmV4cG9ydCBjb25zdCBhZGRBdWRpb1dvcmtsZXRNb2R1bGUgPSBpc1NlY3VyZUNvbnRleHRcbiAgICA/IGNyZWF0ZUFkZEF1ZGlvV29ya2xldE1vZHVsZShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVFdmFsdWF0ZVNvdXJjZSh3aW5kb3cpLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgY3JlYXRlRmV0Y2hTb3VyY2UoY3JlYXRlQWJvcnRFcnJvciksIGdldE5hdGl2ZUNvbnRleHQsIGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5ldyBXZWFrTWFwKCksIG5ldyBXZWFrTWFwKCksIGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBcbiAgICAvLyBAdG9kbyB3aW5kb3cgaXMgZ3VhcmFudGVlZCB0byBiZSBkZWZpbmVkIGJlY2F1c2UgaXNTZWN1cmVDb250ZXh0IGNoZWNrcyB0aGF0IGFzIHdlbGwuXG4gICAgd2luZG93KVxuICAgIDogdW5kZWZpbmVkO1xuY29uc3QgaXNOYXRpdmVDb250ZXh0ID0gY3JlYXRlSXNOYXRpdmVDb250ZXh0KGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGRlY29kZUF1ZGlvRGF0YSA9IGNyZWF0ZURlY29kZUF1ZGlvRGF0YShhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZURhdGFDbG9uZUVycm9yLCBjcmVhdGVFbmNvZGluZ0Vycm9yLCBuZXcgV2Vha1NldCgpLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUNvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgdGVzdFByb21pc2VTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmNvbnN0IGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZUJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihhZGRBdWRpb1dvcmtsZXRNb2R1bGUsIGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IsIGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yLCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IsIGRlY29kZUF1ZGlvRGF0YSwgZGVsYXlOb2RlQ29uc3RydWN0b3IsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciwgZ2Fpbk5vZGVDb25zdHJ1Y3RvciwgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yLCBwYW5uZXJOb2RlQ29uc3RydWN0b3IsIHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yLCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IsIHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IpO1xuY29uc3QgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVGYWN0b3J5KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0KTtcbmNvbnN0IGF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5leHBvcnQgeyBhdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBBdWRpb0NvbnRleHQgfTtcbmNvbnN0IGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2Rlcyh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlKTtcbmNvbnN0IGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKTtcbmNvbnN0IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzKGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlRGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKTtcbmNvbnN0IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzKGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyhhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIGdldFZhbHVlRm9yS2V5KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlckZhY3RvcnkoY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWN0b3J5KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciA9IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlKTtcbmNvbnN0IHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSk7XG4vLyBUaGUgQXVkaW9Xb3JrbGV0Tm9kZSBjb25zdHJ1Y3RvciBpcyBvbmx5IGF2YWlsYWJsZSBpbiBhIFNlY3VyZUNvbnRleHQuXG5jb25zdCBhdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSBpc1NlY3VyZUNvbnRleHRcbiAgICA/IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zLCBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSwgd3JhcEV2ZW50TGlzdGVuZXIpXG4gICAgOiB1bmRlZmluZWQ7XG5leHBvcnQgeyBhdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgYXMgQXVkaW9Xb3JrbGV0Tm9kZSB9O1xuZXhwb3J0IHsgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yIGFzIEJpcXVhZEZpbHRlck5vZGUgfTtcbmV4cG9ydCB7IGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IgYXMgQ2hhbm5lbE1lcmdlck5vZGUgfTtcbmV4cG9ydCB7IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciBhcyBDaGFubmVsU3BsaXR0ZXJOb2RlIH07XG5leHBvcnQgeyBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgYXMgQ29udm9sdmVyTm9kZSB9O1xuZXhwb3J0IHsgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgQ29uc3RhbnRTb3VyY2VOb2RlIH07XG5leHBvcnQgeyBkZWxheU5vZGVDb25zdHJ1Y3RvciBhcyBEZWxheU5vZGUgfTtcbmV4cG9ydCB7IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciBhcyBEeW5hbWljc0NvbXByZXNzb3JOb2RlIH07XG5leHBvcnQgeyBnYWluTm9kZUNvbnN0cnVjdG9yIGFzIEdhaW5Ob2RlIH07XG5leHBvcnQgeyBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgYXMgSUlSRmlsdGVyTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgfTtcbmNvbnN0IG1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuZXhwb3J0IHsgbWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIE1pbmltYWxBdWRpb0NvbnRleHQgfTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVDcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3Qgc3RhcnRSZW5kZXJpbmcgPSBjcmVhdGVTdGFydFJlbmRlcmluZyhhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyk7XG5jb25zdCBtaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzdGFydFJlbmRlcmluZyk7XG5leHBvcnQgeyBtaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIE1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0IH07XG5jb25zdCBvZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzdGFydFJlbmRlcmluZyk7XG5leHBvcnQgeyBvZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgT2ZmbGluZUF1ZGlvQ29udGV4dCB9O1xuZXhwb3J0IHsgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciBhcyBPc2NpbGxhdG9yTm9kZSB9O1xuZXhwb3J0IHsgcGFubmVyTm9kZUNvbnN0cnVjdG9yIGFzIFBhbm5lck5vZGUgfTtcbmV4cG9ydCB7IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yIGFzIFBlcmlvZGljV2F2ZSB9O1xuZXhwb3J0IHsgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yIGFzIFN0ZXJlb1Bhbm5lck5vZGUgfTtcbmV4cG9ydCB7IHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgYXMgV2F2ZVNoYXBlck5vZGUgfTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0KENPTlRFWFRfU1RPUkUsIGlzTmF0aXZlQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvTm9kZSA9IGNyZWF0ZUlzQW55QXVkaW9Ob2RlKEFVRElPX05PREVfU1RPUkUsIGlzTmF0aXZlQXVkaW9Ob2RlKTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvUGFyYW0gPSBjcmVhdGVJc0FueUF1ZGlvUGFyYW0oQVVESU9fUEFSQU1fU1RPUkUsIGlzTmF0aXZlQXVkaW9QYXJhbSk7XG5leHBvcnQgY29uc3QgaXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0KENPTlRFWFRfU1RPUkUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgaXNTdXBwb3J0ZWQgPSAoKSA9PiBjcmVhdGVJc1N1cHBvcnRlZFByb21pc2UoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNTdWJhcnJheVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dENsb3NlTWV0aG9kU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb0NvbnRleHREZWNvZGVBdWRpb0RhdGFNZXRob2RUeXBlRXJyb3JTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRPcHRpb25zU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb05vZGVDb25uZWN0TWV0aG9kU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yTm9PdXRwdXRzU3VwcG9ydChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDaGFubmVsTWVyZ2VyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnN0YW50U291cmNlTm9kZUFjY3VyYXRlU2NoZWR1bGluZ1N1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVCdWZmZXJSZWFzc2lnbmFiaWxpdHlTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCB0ZXN0RG9tRXhjZXB0aW9uQ29uc3RydWN0b3JTdXBwb3J0LCBjcmVhdGVUZXN0SXNTZWN1cmVDb250ZXh0U3VwcG9ydCh3aW5kb3cpLCBjcmVhdGVUZXN0TWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVNZWRpYVN0cmVhbVdpdGhvdXRBdWRpb1RyYWNrU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RTdGVyZW9QYW5uZXJOb2RlRGVmYXVsdFZhbHVlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCB0ZXN0VHJhbnNmZXJhYmxlc1N1cHBvcnQpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bW9kdWxlLmpzLm1hcCIsIi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIHN0YXRlbWVudCBpcyB0cnVlLCBvdGhlcndpc2UgaW52b2tlIHRoZSBlcnJvci5cbiAqIEBwYXJhbSBzdGF0ZW1lbnRcbiAqIEBwYXJhbSBlcnJvciBUaGUgbWVzc2FnZSB3aGljaCBpcyBwYXNzZWQgaW50byBhbiBFcnJvclxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KHN0YXRlbWVudCwgZXJyb3IpIHtcbiAgICBpZiAoIXN0YXRlbWVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIHdpdGhpbiB0aGUgcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFJhbmdlKHZhbHVlLCBndGUsIGx0ZSA9IEluZmluaXR5KSB7XG4gICAgaWYgKCEoZ3RlIDw9IHZhbHVlICYmIHZhbHVlIDw9IGx0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFZhbHVlIG11c3QgYmUgd2l0aGluIFske2d0ZX0sICR7bHRlfV0sIGdvdDogJHt2YWx1ZX1gKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBpcyB3aXRoaW4gdGhlIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRDb250ZXh0UnVubmluZyhjb250ZXh0KSB7XG4gICAgLy8gYWRkIGEgd2FybmluZyBpZiB0aGUgY29udGV4dCBpcyBub3Qgc3RhcnRlZFxuICAgIGlmICghY29udGV4dC5pc09mZmxpbmUgJiYgY29udGV4dC5zdGF0ZSAhPT0gXCJydW5uaW5nXCIpIHtcbiAgICAgICAgd2FybihcIlRoZSBBdWRpb0NvbnRleHQgaXMgXFxcInN1c3BlbmRlZFxcXCIuIEludm9rZSBUb25lLnN0YXJ0KCkgZnJvbSBhIHVzZXIgYWN0aW9uIHRvIHN0YXJ0IHRoZSBhdWRpby5cIik7XG4gICAgfVxufVxuLyoqXG4gKiBUaGUgZGVmYXVsdCBsb2dnZXIgaXMgdGhlIGNvbnNvbGVcbiAqL1xubGV0IGRlZmF1bHRMb2dnZXIgPSBjb25zb2xlO1xuLyoqXG4gKiBTZXQgdGhlIGxvZ2dpbmcgaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRMb2dnZXIobG9nZ2VyKSB7XG4gICAgZGVmYXVsdExvZ2dlciA9IGxvZ2dlcjtcbn1cbi8qKlxuICogTG9nIGFueXRoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2coLi4uYXJncykge1xuICAgIGRlZmF1bHRMb2dnZXIubG9nKC4uLmFyZ3MpO1xufVxuLyoqXG4gKiBXYXJuIGFueXRoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YXJuKC4uLmFyZ3MpIHtcbiAgICBkZWZhdWx0TG9nZ2VyLndhcm4oLi4uYXJncyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWJ1Zy5qcy5tYXAiLCIvKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWYoYXJnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwidW5kZWZpbmVkXCI7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBub3QgdW5kZWZpbmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZmluZWQoYXJnKSB7XG4gICAgcmV0dXJuICFpc1VuZGVmKGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBhIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB0eXBlb2YgYXJnID09PSBcImZ1bmN0aW9uXCI7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgbnVtYmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcIm51bWJlclwiKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgYW4gb2JqZWN0IGxpdGVyYWwgKGkuZS4gYHt9YCk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSBcIltvYmplY3QgT2JqZWN0XVwiICYmIGFyZy5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBib29sZWFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICAgIHJldHVybiAodHlwZW9mIGFyZyA9PT0gXCJib29sZWFuXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhbiBBcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgICByZXR1cm4gKEFycmF5LmlzQXJyYXkoYXJnKSk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgaW4gdGhlIGZvcm0gb2YgYSBub3RlIGluIHNjaWVudGlmaWMgcGl0Y2ggbm90YXRpb24uXG4gKiBlLmcuIFwiQzRcIlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb3RlKGFyZykge1xuICAgIHJldHVybiBpc1N0cmluZyhhcmcpICYmIC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2kudGVzdChhcmcpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHlwZUNoZWNrLmpzLm1hcCIsImltcG9ydCB7IEF1ZGlvQ29udGV4dCBhcyBzdGRBdWRpb0NvbnRleHQsIEF1ZGlvV29ya2xldE5vZGUgYXMgc3RkQXVkaW9Xb3JrbGV0Tm9kZSwgT2ZmbGluZUF1ZGlvQ29udGV4dCBhcyBzdGRPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGlvQ29udGV4dChvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBzdGRBdWRpb0NvbnRleHQob3B0aW9ucyk7XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0KGNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICByZXR1cm4gbmV3IHN0ZE9mZmxpbmVBdWRpb0NvbnRleHQoY2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG59XG4vKipcbiAqIEEgcmVmZXJlbmNlIHRvIHRoZSB3aW5kb3cgb2JqZWN0XG4gKiBAaGlkZGVuXG4gKi9cbmV4cG9ydCBjb25zdCB0aGVXaW5kb3cgPSB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiA/IHNlbGYgOiBudWxsO1xuLyoqXG4gKiBJZiB0aGUgYnJvd3NlciBoYXMgYSB3aW5kb3cgb2JqZWN0IHdoaWNoIGhhcyBhbiBBdWRpb0NvbnRleHRcbiAqIEBoaWRkZW5cbiAqL1xuZXhwb3J0IGNvbnN0IGhhc0F1ZGlvQ29udGV4dCA9IHRoZVdpbmRvdyAmJlxuICAgICh0aGVXaW5kb3cuaGFzT3duUHJvcGVydHkoXCJBdWRpb0NvbnRleHRcIikgfHwgdGhlV2luZG93Lmhhc093blByb3BlcnR5KFwid2Via2l0QXVkaW9Db250ZXh0XCIpKTtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpIHtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKHN0ZEF1ZGlvV29ya2xldE5vZGUpLCBcIlRoaXMgbm9kZSBvbmx5IHdvcmtzIGluIGEgc2VjdXJlIGNvbnRleHQgKGh0dHBzIG9yIGxvY2FsaG9zdClcIik7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBuZXcgc3RkQXVkaW9Xb3JrbGV0Tm9kZShjb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbn1cbi8qKlxuICogVGhpcyBwcm9taXNlIHJlc29sdmVzIHRvIGEgYm9vbGVhbiB3aGljaCBpbmRpY2F0ZXMgaWYgdGhlXG4gKiBmdW5jdGlvbmFsaXR5IGlzIHN1cHBvcnRlZCB3aXRoaW4gdGhlIGN1cnJlbnRseSB1c2VkIGJyb3dzZS5cbiAqIFRha2VuIGZyb20gW3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XShodHRwczovL2dpdGh1Yi5jb20vY2hyaXNndXR0YW5kaW4vc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQjaXNzdXBwb3J0ZWQpXG4gKi9cbmV4cG9ydCB7IGlzU3VwcG9ydGVkIGFzIHN1cHBvcnRlZCB9IGZyb20gXCJzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXVkaW9Db250ZXh0LmpzLm1hcCIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XHJcbiAgICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cclxuICAgIHZhciBraW5kID0gY29udGV4dEluLmtpbmQsIGtleSA9IGtpbmQgPT09IFwiZ2V0dGVyXCIgPyBcImdldFwiIDoga2luZCA9PT0gXCJzZXR0ZXJcIiA/IFwic2V0XCIgOiBcInZhbHVlXCI7XHJcbiAgICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xyXG4gICAgdmFyIF8sIGRvbmUgPSBmYWxzZTtcclxuICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbikgY29udGV4dFtwXSA9IHAgPT09IFwiYWNjZXNzXCIgPyB7fSA6IGNvbnRleHRJbltwXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcclxuICAgICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAoMCwgZGVjb3JhdG9yc1tpXSkoa2luZCA9PT0gXCJhY2Nlc3NvclwiID8geyBnZXQ6IGRlc2NyaXB0b3IuZ2V0LCBzZXQ6IGRlc2NyaXB0b3Iuc2V0IH0gOiBkZXNjcmlwdG9yW2tleV0sIGNvbnRleHQpO1xyXG4gICAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkXCIpO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuaW5pdCkpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcclxuICAgICAgICAgICAgaWYgKGtpbmQgPT09IFwiZmllbGRcIikgaW5pdGlhbGl6ZXJzLnB1c2goXyk7XHJcbiAgICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XHJcbiAgICBkb25lID0gdHJ1ZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3J1bkluaXRpYWxpemVycyh0aGlzQXJnLCBpbml0aWFsaXplcnMsIHZhbHVlKSB7XHJcbiAgICB2YXIgdXNlVmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFsdWUgPSB1c2VWYWx1ZSA/IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcsIHZhbHVlKSA6IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcclxuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIiA/IHggOiBcIlwiLmNvbmNhdCh4KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NldEZ1bmN0aW9uTmFtZShmLCBuYW1lLCBwcmVmaXgpIHtcclxuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzeW1ib2xcIikgbmFtZSA9IG5hbWUuZGVzY3JpcHRpb24gPyBcIltcIi5jb25jYXQobmFtZS5kZXNjcmlwdGlvbiwgXCJdXCIpIDogXCJcIjtcclxuICAgIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogZmFsc2UgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuIiwiLyoqXG4gKiBBIGNsYXNzIHdoaWNoIHByb3ZpZGVzIGEgcmVsaWFibGUgY2FsbGJhY2sgdXNpbmcgZWl0aGVyXG4gKiBhIFdlYiBXb3JrZXIsIG9yIGlmIHRoYXQgaXNuJ3Qgc3VwcG9ydGVkLCBmYWxscyBiYWNrIHRvIHNldFRpbWVvdXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrZXIge1xuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCB0eXBlLCB1cGRhdGVJbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgPSB1cGRhdGVJbnRlcnZhbDtcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBjbG9jayBzb3VyY2UgZm9yIHRoZSBmaXJzdCB0aW1lXG4gICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgd2ViIHdvcmtlclxuICAgICAqL1xuICAgIF9jcmVhdGVXb3JrZXIoKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbXG4gICAgICAgICAgICAvKiBqYXZhc2NyaXB0ICovIGBcblx0XHRcdC8vIHRoZSBpbml0aWFsIHRpbWVvdXQgdGltZVxuXHRcdFx0bGV0IHRpbWVvdXRUaW1lID0gICR7KHRoaXMuX3VwZGF0ZUludGVydmFsICogMTAwMCkudG9GaXhlZCgxKX07XG5cdFx0XHQvLyBvbm1lc3NhZ2UgY2FsbGJhY2tcblx0XHRcdHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24obXNnKXtcblx0XHRcdFx0dGltZW91dFRpbWUgPSBwYXJzZUludChtc2cuZGF0YSk7XG5cdFx0XHR9O1xuXHRcdFx0Ly8gdGhlIHRpY2sgZnVuY3Rpb24gd2hpY2ggcG9zdHMgYSBtZXNzYWdlXG5cdFx0XHQvLyBhbmQgc2NoZWR1bGVzIGEgbmV3IHRpY2tcblx0XHRcdGZ1bmN0aW9uIHRpY2soKXtcblx0XHRcdFx0c2V0VGltZW91dCh0aWNrLCB0aW1lb3V0VGltZSk7XG5cdFx0XHRcdHNlbGYucG9zdE1lc3NhZ2UoJ3RpY2snKTtcblx0XHRcdH1cblx0XHRcdC8vIGNhbGwgdGljayBpbml0aWFsbHlcblx0XHRcdHRpY2soKTtcblx0XHRcdGBcbiAgICAgICAgXSwgeyB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiIH0pO1xuICAgICAgICBjb25zdCBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTtcbiAgICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuX3dvcmtlciA9IHdvcmtlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgdGltZW91dCBsb29wXG4gICAgICovXG4gICAgX2NyZWF0ZVRpbWVvdXQoKSB7XG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRpbWVvdXQoKTtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XG4gICAgICAgIH0sIHRoaXMuX3VwZGF0ZUludGVydmFsICogMTAwMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB0aGUgY2xvY2sgc291cmNlLlxuICAgICAqL1xuICAgIF9jcmVhdGVDbG9jaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwid29ya2VyXCIpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlV29ya2VyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIHdvcmtlcnMgbm90IHN1cHBvcnRlZCwgZmFsbGJhY2sgdG8gdGltZW91dFxuICAgICAgICAgICAgICAgIHRoaXMuX3R5cGUgPSBcInRpbWVvdXRcIjtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFwidGltZW91dFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVUaW1lb3V0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAgdGhlIGN1cnJlbnQgY2xvY2sgc291cmNlXG4gICAgICovXG4gICAgX2Rpc3Bvc2VDbG9jaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVvdXQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl93b3JrZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci5vbm1lc3NhZ2UgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByYXRlIGluIHNlY29uZHMgdGhlIHRpY2tlciB3aWxsIHVwZGF0ZVxuICAgICAqL1xuICAgIGdldCB1cGRhdGVJbnRlcnZhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZUludGVydmFsO1xuICAgIH1cbiAgICBzZXQgdXBkYXRlSW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgPSBNYXRoLm1heChpbnRlcnZhbCwgMTI4IC8gNDQxMDApO1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnBvc3RNZXNzYWdlKE1hdGgubWF4KGludGVydmFsICogMTAwMCwgMSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSB0aWNrZXIsIGVpdGhlciBhIHdvcmtlciBvciBhIHRpbWVvdXRcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUNsb2NrKCk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VDbG9jaygpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tlci5qcy5tYXAiLCJpbXBvcnQgeyBpc0FueUF1ZGlvQ29udGV4dCwgaXNBbnlBdWRpb05vZGUsIGlzQW55QXVkaW9QYXJhbSwgaXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0LCB9IGZyb20gXCJzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFwiO1xuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZW9mIEF1ZGlvUGFyYW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9QYXJhbShhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb1BhcmFtKGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9Ob2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvTm9kZShhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb05vZGUoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGluc3RhbmNlb2YgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZykge1xuICAgIHJldHVybiBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvQ29udGV4dChhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb0NvbnRleHQoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGluc3RhbmNlb2YgYW4gQXVkaW9CdWZmZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9CdWZmZXIoYXJnKSB7XG4gICAgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIEF1ZGlvQnVmZmVyO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWR2YW5jZWRUeXBlQ2hlY2suanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb0J1ZmZlciwgaXNBdWRpb05vZGUsIGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1VuZGVmIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIFNvbWUgb2JqZWN0cyBzaG91bGQgbm90IGJlIG1lcmdlZFxuICovXG5mdW5jdGlvbiBub0NvcHkoa2V5LCBhcmcpIHtcbiAgICByZXR1cm4ga2V5ID09PSBcInZhbHVlXCIgfHwgaXNBdWRpb1BhcmFtKGFyZykgfHwgaXNBdWRpb05vZGUoYXJnKSB8fCBpc0F1ZGlvQnVmZmVyKGFyZyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZGVlcE1lcmdlKHRhcmdldCwgLi4uc291cmNlcykge1xuICAgIGlmICghc291cmNlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgIGlmIChpc09iamVjdCh0YXJnZXQpICYmIGlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAobm9Db3B5KGtleSwgc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHNvdXJjZVtrZXldKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0W2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHt9IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWVwTWVyZ2UodGFyZ2V0W2tleV0sIHNvdXJjZVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB7IFtrZXldOiBzb3VyY2Vba2V5XSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIGRlZXBNZXJnZSh0YXJnZXQsIC4uLnNvdXJjZXMpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBhcnJheXMgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgZWFjaCBvZiB0aGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbHMoYXJyYXlBLCBhcnJheUIpIHtcbiAgICByZXR1cm4gYXJyYXlBLmxlbmd0aCA9PT0gYXJyYXlCLmxlbmd0aCAmJiBhcnJheUEuZXZlcnkoKGVsZW1lbnQsIGluZGV4KSA9PiBhcnJheUJbaW5kZXhdID09PSBlbGVtZW50KTtcbn1cbi8qKlxuICogQ29udmVydCBhbiBhcmdzIGFycmF5IGludG8gYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uc0Zyb21Bcmd1bWVudHMoZGVmYXVsdHMsIGFyZ3NBcnJheSwga2V5cyA9IFtdLCBvYmpLZXkpIHtcbiAgICBjb25zdCBvcHRzID0ge307XG4gICAgY29uc3QgYXJncyA9IEFycmF5LmZyb20oYXJnc0FycmF5KTtcbiAgICAvLyBpZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gb2JqZWN0IGFuZCBoYXMgYW4gb2JqZWN0IGtleVxuICAgIGlmIChpc09iamVjdChhcmdzWzBdKSAmJiBvYmpLZXkgJiYgIVJlZmxlY3QuaGFzKGFyZ3NbMF0sIG9iaktleSkpIHtcbiAgICAgICAgLy8gaWYgaXQncyBub3QgcGFydCBvZiB0aGUgZGVmYXVsdHNcbiAgICAgICAgY29uc3QgcGFydE9mRGVmYXVsdHMgPSBPYmplY3Qua2V5cyhhcmdzWzBdKS5zb21lKGtleSA9PiBSZWZsZWN0LmhhcyhkZWZhdWx0cywga2V5KSk7XG4gICAgICAgIGlmICghcGFydE9mRGVmYXVsdHMpIHtcbiAgICAgICAgICAgIC8vIG1lcmdlIHRoYXQga2V5XG4gICAgICAgICAgICBkZWVwTWVyZ2Uob3B0cywgeyBbb2JqS2V5XTogYXJnc1swXSB9KTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgb2JqIGtleSBmcm9tIHRoZSBrZXlzXG4gICAgICAgICAgICBrZXlzLnNwbGljZShrZXlzLmluZGV4T2Yob2JqS2V5KSwgMSk7XG4gICAgICAgICAgICAvLyBzaGlmdCB0aGUgZmlyc3QgYXJndW1lbnQgb2ZmXG4gICAgICAgICAgICBhcmdzLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGlzT2JqZWN0KGFyZ3NbMF0pKSB7XG4gICAgICAgIGRlZXBNZXJnZShvcHRzLCBhcmdzWzBdKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChhcmdzW2ldKSkge1xuICAgICAgICAgICAgICAgIG9wdHNba2V5c1tpXV0gPSBhcmdzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZWVwTWVyZ2UoZGVmYXVsdHMsIG9wdHMpO1xufVxuLyoqXG4gKiBSZXR1cm4gdGhpcyBpbnN0YW5jZXMgZGVmYXVsdCB2YWx1ZXMgYnkgY2FsbGluZyBDb25zdHJ1Y3Rvci5nZXREZWZhdWx0cygpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZShpbnN0YW5jZSkge1xuICAgIHJldHVybiBpbnN0YW5jZS5jb25zdHJ1Y3Rvci5nZXREZWZhdWx0cygpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmYWxsYmFjayBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIHVuZGVmaW5lZC5cbiAqIFRha2UgYW4gYXJyYXkgb2YgYXJndW1lbnRzIGFuZCByZXR1cm4gYSBmb3JtYXR0ZWQgb3B0aW9ucyBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QXJnKGdpdmVuLCBmYWxsYmFjaykge1xuICAgIGlmIChpc1VuZGVmKGdpdmVuKSkge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2s7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gZ2l2ZW47XG4gICAgfVxufVxuLyoqXG4gKiBSZW1vdmUgYWxsIG9mIHRoZSBwcm9wZXJ0aWVzIGJlbG9uZ2luZyB0byBvbWl0IGZyb20gb2JqLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb21pdEZyb21PYmplY3Qob2JqLCBvbWl0KSB7XG4gICAgb21pdC5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXMob2JqLCBwcm9wKSkge1xuICAgICAgICAgICAgZGVsZXRlIG9ialtwcm9wXTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWZhdWx0cy5qcy5tYXAiLCIvKipcbiAqIFRvbmUuanNcbiAqIEBhdXRob3IgWW90YW0gTWFublxuICogQGxpY2Vuc2UgaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVCBNSVQgTGljZW5zZVxuICogQGNvcHlyaWdodCAyMDE0LTIwMTkgWW90YW0gTWFublxuICovXG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb25cIjtcbmltcG9ydCB7IHRoZVdpbmRvdyB9IGZyb20gXCIuL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEBjbGFzcyAgVG9uZSBpcyB0aGUgYmFzZSBjbGFzcyBvZiBhbGwgb3RoZXIgY2xhc3Nlcy5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRERUJVR0dJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXQgdGhpcyBkZWJ1ZyBmbGFnIHRvIGxvZyBhbGwgZXZlbnRzIHRoYXQgaGFwcGVuIGluIHRoaXMgY2xhc3MuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlYnVnID0gZmFsc2U7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdERJU1BPU0lOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgaW5zdGFuY2Ugd2FzIGRpc3Bvc2VkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93YXNEaXNwb3NlZCA9IGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFsbCBvZiB0aGUgZGVmYXVsdCBvcHRpb25zIGJlbG9uZ2luZyB0byB0aGUgY2xhc3MuXG4gICAgICovXG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFByaW50cyB0aGUgb3V0cHV0cyB0byB0aGUgY29uc29sZSBsb2cgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAgICAgKiBQcmludHMgdGhlIGNvbnRlbnRzIG9ubHkgaWYgZWl0aGVyIHRoZSBvYmplY3QgaGFzIGEgcHJvcGVydHlcbiAgICAgKiBjYWxsZWQgYGRlYnVnYCBzZXQgdG8gdHJ1ZSwgb3IgYSB2YXJpYWJsZSBjYWxsZWQgVE9ORV9ERUJVR19DTEFTU1xuICAgICAqIGlzIHNldCB0byB0aGUgbmFtZSBvZiB0aGUgY2xhc3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogLy8gcHJpbnRzIGFsbCBsb2dzIG9yaWdpbmF0aW5nIGZyb20gdGhpcyBvc2NpbGxhdG9yXG4gICAgICogb3NjLmRlYnVnID0gdHJ1ZTtcbiAgICAgKiAvLyBjYWxscyB0byBzdGFydC9zdG9wIHdpbGwgcHJpbnQgaW4gdGhlIGNvbnNvbGVcbiAgICAgKiBvc2Muc3RhcnQoKTtcbiAgICAgKi9cbiAgICBsb2coLi4uYXJncykge1xuICAgICAgICAvLyBpZiB0aGUgb2JqZWN0IGlzIGVpdGhlciBzZXQgdG8gZGVidWcgPSB0cnVlXG4gICAgICAgIC8vIG9yIGlmIHRoZXJlIGlzIGEgc3RyaW5nIG9uIHRoZSBUb25lLmdsb2JhbC53aXRoIHRoZSBjbGFzcyBuYW1lXG4gICAgICAgIGlmICh0aGlzLmRlYnVnIHx8ICh0aGVXaW5kb3cgJiYgdGhpcy50b1N0cmluZygpID09PSB0aGVXaW5kb3cuVE9ORV9ERUJVR19DTEFTUykpIHtcbiAgICAgICAgICAgIGxvZyh0aGlzLCAuLi5hcmdzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBkaXNjb25uZWN0IGFuZCBkaXNwb3NlLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuX3dhc0Rpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyBpZiB0aGUgaW5zdGFuY2Ugd2FzIGRpc3Bvc2VkLiAnRGlzcG9zaW5nJyBhblxuICAgICAqIGluc3RhbmNlIG1lYW5zIHRoYXQgYWxsIG9mIHRoZSBXZWIgQXVkaW8gbm9kZXMgdGhhdCB3ZXJlXG4gICAgICogY3JlYXRlZCBmb3IgdGhlIGluc3RhbmNlIGFyZSBkaXNjb25uZWN0ZWQgYW5kIGZyZWVkIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24uXG4gICAgICovXG4gICAgZ2V0IGRpc3Bvc2VkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2FzRGlzcG9zZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGNsYXNzIHRvIGEgc3RyaW5nXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogY29uc29sZS5sb2cob3NjLnRvU3RyaW5nKCkpO1xuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgIH1cbn1cbi8qKlxuICogVGhlIHZlcnNpb24gbnVtYmVyIHNlbXZlclxuICovXG5Ub25lLnZlcnNpb24gPSB2ZXJzaW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZS5qcy5tYXAiLCIvKipcbiAqIFRoZSB0aHJlc2hvbGQgZm9yIGNvcnJlY3RuZXNzIGZvciBvcGVyYXRvcnMuIExlc3MgdGhhbiBvbmUgc2FtcGxlIGV2ZW5cbiAqIGF0IHZlcnkgaGlnaCBzYW1wbGluZyByYXRlcyAoZS5nLiBgMWUtNiA8IDEgLyAxOTIwMDBgKS5cbiAqL1xuY29uc3QgRVBTSUxPTiA9IDFlLTY7XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBncmVhdGVyIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gR1QoYSwgYikge1xuICAgIHJldHVybiBhID4gYiArIEVQU0lMT047XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gR1RFKGEsIGIpIHtcbiAgICByZXR1cm4gR1QoYSwgYikgfHwgRVEoYSwgYik7XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBsZXNzIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gTFQoYSwgYikge1xuICAgIHJldHVybiBhICsgRVBTSUxPTiA8IGI7XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBsZXNzIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gRVEoYSwgYikge1xuICAgIHJldHVybiBNYXRoLmFicyhhIC0gYikgPCBFUFNJTE9OO1xufVxuLyoqXG4gKiBDbGFtcCB0aGUgdmFsdWUgd2l0aGluIHRoZSBnaXZlbiByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhbXAodmFsdWUsIG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KE1hdGgubWluKHZhbHVlLCBtYXgpLCBtaW4pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWF0aC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4vRGVmYXVsdHNcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuL0RlYnVnXCI7XG5pbXBvcnQgeyBFUSwgR1QsIEdURSwgTFQgfSBmcm9tIFwiLi9NYXRoXCI7XG4vKipcbiAqIEEgVGltZWxpbmUgY2xhc3MgZm9yIHNjaGVkdWxpbmcgYW5kIG1haW50YWluaW5nIHN0YXRlXG4gKiBhbG9uZyBhIHRpbWVsaW5lLiBBbGwgZXZlbnRzIG11c3QgaGF2ZSBhIFwidGltZVwiIHByb3BlcnR5LlxuICogSW50ZXJuYWxseSwgZXZlbnRzIGFyZSBzdG9yZWQgaW4gdGltZSBvcmRlciBmb3IgZmFzdFxuICogcmV0cmlldmFsLlxuICovXG5leHBvcnQgY2xhc3MgVGltZWxpbmUgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lbGluZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIHNjaGVkdWxlZCB0aW1lbGluZSBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaW1lbGluZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1lbW9yeVwiXSk7XG4gICAgICAgIHRoaXMubWVtb3J5ID0gb3B0aW9ucy5tZW1vcnk7XG4gICAgICAgIHRoaXMuaW5jcmVhc2luZyA9IG9wdGlvbnMuaW5jcmVhc2luZztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWVtb3J5OiBJbmZpbml0eSxcbiAgICAgICAgICAgIGluY3JlYXNpbmc6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnNlcnQgYW4gZXZlbnQgb2JqZWN0IG9udG8gdGhlIHRpbWVsaW5lLiBFdmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgYXR0cmlidXRlLlxuICAgICAqIEBwYXJhbSBldmVudCAgVGhlIGV2ZW50IG9iamVjdCB0byBpbnNlcnQgaW50byB0aGUgdGltZWxpbmUuXG4gICAgICovXG4gICAgYWRkKGV2ZW50KSB7XG4gICAgICAgIC8vIHRoZSBldmVudCBuZWVkcyB0byBoYXZlIGEgdGltZSBhdHRyaWJ1dGVcbiAgICAgICAgYXNzZXJ0KFJlZmxlY3QuaGFzKGV2ZW50LCBcInRpbWVcIiksIFwiVGltZWxpbmU6IGV2ZW50cyBtdXN0IGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVwiKTtcbiAgICAgICAgZXZlbnQudGltZSA9IGV2ZW50LnRpbWUudmFsdWVPZigpO1xuICAgICAgICBpZiAodGhpcy5pbmNyZWFzaW5nICYmIHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0VmFsdWUgPSB0aGlzLl90aW1lbGluZVt0aGlzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgYXNzZXJ0KEdURShldmVudC50aW1lLCBsYXN0VmFsdWUudGltZSksIFwiVGhlIHRpbWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxhc3Qgc2NoZWR1bGVkIHRpbWVcIik7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5wdXNoKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUuc3BsaWNlKGluZGV4ICsgMSwgMCwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgbW9yZSB0aGFuIHRoZSBtZW1vcnksIHJlbW92ZSB0aGUgcHJldmlvdXMgb25lc1xuICAgICAgICBpZiAodGhpcy5sZW5ndGggPiB0aGlzLm1lbW9yeSkge1xuICAgICAgICAgICAgY29uc3QgZGlmZiA9IHRoaXMubGVuZ3RoIC0gdGhpcy5tZW1vcnk7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoMCwgZGlmZik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBldmVudCBmcm9tIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBldmVudCAgVGhlIGV2ZW50IG9iamVjdCB0byByZW1vdmUgZnJvbSB0aGUgbGlzdC5cbiAgICAgKiBAcmV0dXJucyB7VGltZWxpbmV9IHRoaXNcbiAgICAgKi9cbiAgICByZW1vdmUoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBuZWFyZXN0IGV2ZW50IHdob3NlIHRpbWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0KHRpbWUsIHBhcmFtID0gXCJ0aW1lXCIpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSwgcGFyYW0pO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgd2l0aG91dCByZW1vdmluZyBpdFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBmaXJzdCBldmVudCBvYmplY3RcbiAgICAgKi9cbiAgICBwZWVrKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbMF07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZmlyc3QgZXZlbnQgaW4gdGhlIHRpbWVsaW5lIGFuZCByZW1vdmUgaXRcbiAgICAgKi9cbiAgICBzaGlmdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lLnNoaWZ0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZXZlbnQgd2hpY2ggaXMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0QWZ0ZXIodGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBwYXJhbSk7XG4gICAgICAgIGlmIChpbmRleCArIDEgPCB0aGlzLl90aW1lbGluZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCArIDFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBldmVudCBiZWZvcmUgdGhlIGV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0QmVmb3JlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICAvLyBpZiBpdCdzIGFmdGVyIHRoZSBsYXN0IGl0ZW0sIHJldHVybiB0aGUgbGFzdCBpdGVtXG4gICAgICAgIGlmIChsZW4gPiAwICYmIHRoaXMuX3RpbWVsaW5lW2xlbiAtIDFdLnRpbWUgPCB0aW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbbGVuIC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmIChpbmRleCAtIDEgPj0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZXZlbnRzIGF0IGFuZCBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5fc2VhcmNoKGFmdGVyKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2luZGV4XS50aW1lLCBhZnRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBmaXJzdCBpdGVtIHdpdGggdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChFUSh0aGlzLl90aW1lbGluZVtpXS50aW1lLCBhZnRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IHRoaXMuX3RpbWVsaW5lLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3RpbWVsaW5lLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGl0ZW0ncyB0aW1lXG4gICAgICAgICAgICBpZiAoR1RFKHRoaXMuX3RpbWVsaW5lWzBdLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgYmVmb3JlIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gY2FuY2VsIGJlZm9yZS5cbiAgICAgKi9cbiAgICBjYW5jZWxCZWZvcmUodGltZSkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoaW5kZXggKyAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcHJldmlvdXMgZXZlbnQgaWYgdGhlcmUgaXMgb25lLiBudWxsIG90aGVyd2lzZVxuICAgICAqIEBwYXJhbSAgZXZlbnQgVGhlIGV2ZW50IHRvIGZpbmQgdGhlIHByZXZpb3VzIG9uZSBvZlxuICAgICAqIEByZXR1cm4gVGhlIGV2ZW50IHJpZ2h0IGJlZm9yZSB0aGUgZ2l2ZW4gZXZlbnRcbiAgICAgKi9cbiAgICBwcmV2aW91c0V2ZW50KGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdGltZWxpbmUuaW5kZXhPZihldmVudCk7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRG9lcyBhIGJpbmFyeSBzZWFyY2ggb24gdGhlIHRpbWVsaW5lIGFycmF5IGFuZCByZXR1cm5zIHRoZVxuICAgICAqIG5lYXJlc3QgZXZlbnQgaW5kZXggd2hvc2UgdGltZSBpcyBhZnRlciBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBJZiBhIHRpbWUgaXMgc2VhcmNoZWQgYmVmb3JlIHRoZSBmaXJzdCBpbmRleCBpbiB0aGUgdGltZWxpbmUsIC0xIGlzIHJldHVybmVkLlxuICAgICAqIElmIHRoZSB0aW1lIGlzIGFmdGVyIHRoZSBlbmQsIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBpdGVtIGlzIHJldHVybmVkLlxuICAgICAqL1xuICAgIF9zZWFyY2godGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJlZ2lubmluZyA9IDA7XG4gICAgICAgIGNvbnN0IGxlbiA9IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDtcbiAgICAgICAgbGV0IGVuZCA9IGxlbjtcbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV1bcGFyYW1dIDw9IHRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBsZW4gLSAxO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChiZWdpbm5pbmcgPCBlbmQpIHtcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgbWlkcG9pbnQgZm9yIHJvdWdobHkgZXF1YWwgcGFydGl0aW9uXG4gICAgICAgICAgICBsZXQgbWlkUG9pbnQgPSBNYXRoLmZsb29yKGJlZ2lubmluZyArIChlbmQgLSBiZWdpbm5pbmcpIC8gMik7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50XTtcbiAgICAgICAgICAgIGNvbnN0IG5leHRFdmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50ICsgMV07XG4gICAgICAgICAgICBpZiAoRVEoZXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIC8vIGNob29zZSB0aGUgbGFzdCBvbmUgdGhhdCBoYXMgdGhlIHNhbWUgdGltZVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBtaWRQb2ludDsgaSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlc3RFdmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoRVEodGVzdEV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pZFBvaW50ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKExUKGV2ZW50W3BhcmFtXSwgdGltZSkgJiYgR1QobmV4dEV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWlkUG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChHVChldmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gc2VhcmNoIGxvd2VyXG4gICAgICAgICAgICAgICAgZW5kID0gbWlkUG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzZWFyY2ggdXBwZXJcbiAgICAgICAgICAgICAgICBiZWdpbm5pbmcgPSBtaWRQb2ludCArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBpdGVyYXRvci4gQXBwbGllcyBleHRyYSBzYWZldHkgY2hlY2tzIGZvclxuICAgICAqIHJlbW92aW5nIGl0ZW1zIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIF9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kID0gMCwgdXBwZXJCb3VuZCA9IHRoaXMuX3RpbWVsaW5lLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuc2xpY2UobG93ZXJCb3VuZCwgdXBwZXJCb3VuZCArIDEpLmZvckVhY2goY2FsbGJhY2spO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXlcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBiZWZvcmUgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEJlZm9yZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmICh1cHBlckJvdW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQWZ0ZXIodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBjb25zdCBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYmV0d2VlbiB0aGUgc3RhcnRUaW1lIGFuZCBlbmRUaW1lLlxuICAgICAqIFRoZSB0aW1lcmFuZ2UgaXMgaW5jbHVzaXZlIG9mIHRoZSBzdGFydFRpbWUsIGJ1dCBleGNsdXNpdmUgb2YgdGhlIGVuZFRpbWUuXG4gICAgICogcmFuZ2UgPSBbc3RhcnRUaW1lLCBlbmRUaW1lKS5cbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBlbmRUaW1lIFRoZSBlbmQgb2YgdGhlIHRlc3QgaW50ZXJ2YWwuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2goc3RhcnRUaW1lKTtcbiAgICAgICAgbGV0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2goZW5kVGltZSk7XG4gICAgICAgIGlmIChsb3dlckJvdW5kICE9PSAtMSAmJiB1cHBlckJvdW5kICE9PSAtMSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgIT09IHN0YXJ0VGltZSkge1xuICAgICAgICAgICAgICAgIGxvd2VyQm91bmQgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGV4Y2x1c2l2ZSBvZiB0aGUgZW5kIHRpbWVcbiAgICAgICAgICAgIGlmICh0aGlzLl90aW1lbGluZVt1cHBlckJvdW5kXS50aW1lID09PSBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgdXBwZXJCb3VuZCAtPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobG93ZXJCb3VuZCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIDAsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYXQgb3IgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuIFNpbWlsYXIgdG9cbiAgICAgKiBmb3JFYWNoQWZ0ZXIsIGJ1dCBpbmNsdWRlcyB0aGUgaXRlbShzKSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoRnJvbSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGxldCBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICAvLyB3b3JrIGJhY2t3YXJkcyB1bnRpbCB0aGUgZXZlbnQgdGltZSBpcyBsZXNzIHRoYW4gdGltZVxuICAgICAgICB3aGlsZSAobG93ZXJCb3VuZCA+PSAwICYmIHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgPj0gdGltZSkge1xuICAgICAgICAgICAgbG93ZXJCb3VuZC0tO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBdFRpbWUodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBjb25zdCB1cHBlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAodXBwZXJCb3VuZCAhPT0gLTEgJiYgRVEodGhpcy5fdGltZWxpbmVbdXBwZXJCb3VuZF0udGltZSwgdGltZSkpIHtcbiAgICAgICAgICAgIGxldCBsb3dlckJvdW5kID0gdXBwZXJCb3VuZDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSB1cHBlckJvdW5kOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChFUSh0aGlzLl90aW1lbGluZVtpXS50aW1lLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBsb3dlckJvdW5kID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgIH0sIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWVsaW5lLmpzLm1hcCIsIi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gSU5JVElBTElaSU5HIE5FVyBDT05URVhUXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogQXJyYXkgb2YgY2FsbGJhY2tzIHRvIGludm9rZSB3aGVuIGEgbmV3IGNvbnRleHQgaXMgY3JlYXRlZFxuICovXG5jb25zdCBub3RpZnlOZXdDb250ZXh0ID0gW107XG4vKipcbiAqIFVzZWQgaW50ZXJuYWxseSB0byBzZXR1cCBhIG5ldyBDb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNvbnRleHRJbml0KGNiKSB7XG4gICAgbm90aWZ5TmV3Q29udGV4dC5wdXNoKGNiKTtcbn1cbi8qKlxuICogSW52b2tlIGFueSBjbGFzc2VzIHdoaWNoIG5lZWQgdG8gYWxzbyBiZSBpbml0aWFsaXplZCB3aGVuIGEgbmV3IGNvbnRleHQgaXMgY3JlYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVDb250ZXh0KGN0eCkge1xuICAgIC8vIGFkZCBhbnkgYWRkaXRpb25hbCBtb2R1bGVzXG4gICAgbm90aWZ5TmV3Q29udGV4dC5mb3JFYWNoKGNiID0+IGNiKGN0eCkpO1xufVxuLyoqXG4gKiBBcnJheSBvZiBjYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkXG4gKi9cbmNvbnN0IG5vdGlmeUNsb3NlQ29udGV4dCA9IFtdO1xuLyoqXG4gKiBVc2VkIGludGVybmFsbHkgdG8gdGVhciBkb3duIGEgQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gb25Db250ZXh0Q2xvc2UoY2IpIHtcbiAgICBub3RpZnlDbG9zZUNvbnRleHQucHVzaChjYik7XG59XG5leHBvcnQgZnVuY3Rpb24gY2xvc2VDb250ZXh0KGN0eCkge1xuICAgIC8vIGFkZCBhbnkgYWRkaXRpb25hbCBtb2R1bGVzXG4gICAgbm90aWZ5Q2xvc2VDb250ZXh0LmZvckVhY2goY2IgPT4gY2IoY3R4KSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db250ZXh0SW5pdGlhbGl6YXRpb24uanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIEVtaXR0ZXIgZ2l2ZXMgY2xhc3NlcyB3aGljaCBleHRlbmQgaXRcbiAqIHRoZSBhYmlsaXR5IHRvIGxpc3RlbiBmb3IgYW5kIGVtaXQgZXZlbnRzLlxuICogSW5zcGlyYXRpb24gYW5kIHJlZmVyZW5jZSBmcm9tIEplcm9tZSBFdGllbm5lJ3MgW01pY3JvRXZlbnRdKGh0dHBzOi8vZ2l0aHViLmNvbS9qZXJvbWVldGllbm5lL21pY3JvZXZlbnQuanMpLlxuICogTUlUIChjKSAyMDExIEplcm9tZSBFdGllbm5lLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIEVtaXR0ZXIgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFbWl0dGVyXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJpbmQgYSBjYWxsYmFjayB0byBhIHNwZWNpZmljIGV2ZW50LlxuICAgICAqIEBwYXJhbSAgZXZlbnQgICAgIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZFxuICAgICAqL1xuICAgIG9uKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICAvLyBzcGxpdCB0aGUgZXZlbnRcbiAgICAgICAgY29uc3QgZXZlbnRzID0gZXZlbnQuc3BsaXQoL1xcVysvKTtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX2V2ZW50cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnROYW1lXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50TmFtZV0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNhbGxiYWNrIHdoaWNoIGlzIG9ubHkgaW52b2tlZCBvbmNlXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb25jZShldmVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgYm91bmRDYWxsYmFjayA9ICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBjYWxsYmFjayguLi5hcmdzKTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZXZlbnRcbiAgICAgICAgICAgIHRoaXMub2ZmKGV2ZW50LCBib3VuZENhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vbihldmVudCwgYm91bmRDYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgICAgIFRoZSBldmVudCB0byBzdG9wIGxpc3RlbmluZyB0by5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgd2hpY2ggd2FzIGJvdW5kIHRvIHRoZSBldmVudCB3aXRoIEVtaXR0ZXIub24uXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgbm8gY2FsbGJhY2sgaXMgZ2l2ZW4sIGFsbCBjYWxsYmFja3MgZXZlbnRzIGFyZSByZW1vdmVkLlxuICAgICAqL1xuICAgIG9mZihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gZXZlbnQuc3BsaXQoL1xcVysvKTtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX2V2ZW50cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5kZWYoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBldmVudExpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudExpc3RbaV0gPT09IGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMaXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgYWxsIG9mIHRoZSBjYWxsYmFja3MgYm91bmQgdG8gdGhlIGV2ZW50XG4gICAgICogd2l0aCBhbnkgYXJndW1lbnRzIHBhc3NlZCBpbi5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXG4gICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBmdW5jdGlvbnMgbGlzdGVuaW5nLlxuICAgICAqL1xuICAgIGVtaXQoZXZlbnQsIC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudExpc3QgPSB0aGlzLl9ldmVudHNbZXZlbnRdLnNsaWNlKDApO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBldmVudExpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRMaXN0W2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIEVtaXR0ZXIgZnVuY3Rpb25zIChvbi9vZmYvZW1pdCkgdG8gdGhlIG9iamVjdFxuICAgICAqL1xuICAgIHN0YXRpYyBtaXhpbihjb25zdHIpIHtcbiAgICAgICAgLy8gaW5zdGFuY2UuX2V2ZW50cyA9IHt9O1xuICAgICAgICBbXCJvblwiLCBcIm9uY2VcIiwgXCJvZmZcIiwgXCJlbWl0XCJdLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoRW1pdHRlci5wcm90b3R5cGUsIG5hbWUpO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnN0ci5wcm90b3R5cGUsIG5hbWUsIHByb3BlcnR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVtaXR0ZXIuanMubWFwIiwiaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmV4cG9ydCBjbGFzcyBCYXNlQ29udGV4dCBleHRlbmRzIEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IGZhbHNlO1xuICAgIH1cbiAgICAvKlxuICAgICAqIFRoaXMgaXMgYSBwbGFjZWhvbGRlciBzbyB0aGF0IEpTT04uc3RyaW5naWZ5IGRvZXMgbm90IHRocm93IGFuIGVycm9yXG4gICAgICogVGhpcyBtYXRjaGVzIHdoYXQgSlNPTi5zdHJpbmdpZnkoYXVkaW9Db250ZXh0KSByZXR1cm5zIG9uIGEgbmF0aXZlXG4gICAgICogYXVkaW9Db250ZXh0IGluc3RhbmNlLlxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJhc2VDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVGlja2VyIH0gZnJvbSBcIi4uL2Nsb2NrL1RpY2tlclwiO1xuaW1wb3J0IHsgaXNBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc1N0cmluZyB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Db250ZXh0LCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlLCB9IGZyb20gXCIuL0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgY2xvc2VDb250ZXh0LCBpbml0aWFsaXplQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgQmFzZUNvbnRleHQgfSBmcm9tIFwiLi9CYXNlQ29udGV4dFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dCBleHRlbmRzIEJhc2VDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb250ZXh0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgb2YgdGhlIGNvbnN0YW50cyBBdWRpb0J1ZmZlclNvdXJjZU5vZGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb25zdGFudHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIHNldFRpbWVvdXQgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dHMgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lb3V0IGlkIGNvdW50ZXJcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVvdXRJZHMgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSBpbmRpY2F0b3IgaWYgdGhlIGNvbnRleHQgaGFzIGJlZW4gaW5pdGlhbGl6ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGNvbnRleHQgaXMgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCBvciBhbiBBdWRpb0NvbnRleHRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gQVVESU8gV09SS0xFVFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNYXBzIGEgbW9kdWxlIG5hbWUgdG8gcHJvbWlzZSBvZiB0aGUgYWRkTW9kdWxlIG1ldGhvZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb250ZXh0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1xuICAgICAgICAgICAgXCJjb250ZXh0XCIsXG4gICAgICAgIF0pO1xuICAgICAgICBpZiAob3B0aW9ucy5jb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IGNyZWF0ZUF1ZGlvQ29udGV4dCh7XG4gICAgICAgICAgICAgICAgbGF0ZW5jeUhpbnQ6IG9wdGlvbnMubGF0ZW5jeUhpbnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90aWNrZXIgPSBuZXcgVGlja2VyKHRoaXMuZW1pdC5iaW5kKHRoaXMsIFwidGlja1wiKSwgb3B0aW9ucy5jbG9ja1NvdXJjZSwgb3B0aW9ucy51cGRhdGVJbnRlcnZhbCk7XG4gICAgICAgIHRoaXMub24oXCJ0aWNrXCIsIHRoaXMuX3RpbWVvdXRMb29wLmJpbmQodGhpcykpO1xuICAgICAgICAvLyBmd2QgZXZlbnRzIGZyb20gdGhlIGNvbnRleHRcbiAgICAgICAgdGhpcy5fY29udGV4dC5vbnN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhdGVjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX3NldExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpO1xuICAgICAgICB0aGlzLmxvb2tBaGVhZCA9IG9wdGlvbnMubG9va0FoZWFkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjbG9ja1NvdXJjZTogXCJ3b3JrZXJcIixcbiAgICAgICAgICAgIGxhdGVuY3lIaW50OiBcImludGVyYWN0aXZlXCIsXG4gICAgICAgICAgICBsb29rQWhlYWQ6IDAuMSxcbiAgICAgICAgICAgIHVwZGF0ZUludGVydmFsOiAwLjA1LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggc2V0dGluZyB1cCB0aGUgY29udGV4dC4gKipZb3UgdXN1YWxseSBkbyBub3QgbmVlZCB0byBkbyB0aGlzIG1hbnVhbGx5LioqXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICAgICAgICAgIGluaXRpYWxpemVDb250ZXh0KHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJBU0UgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXJTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIH1cbiAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMpO1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIobnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMpO1xuICAgIH1cbiAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ29uc3RhbnRTb3VyY2UoKTtcbiAgICB9XG4gICAgY3JlYXRlQ29udm9sdmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZURlbGF5KG1heERlbGF5VGltZSk7XG4gICAgfVxuICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgfVxuICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICB9XG4gICAgY3JlYXRlSUlSRmlsdGVyKGZlZWRGb3J3YXJkLCBmZWVkYmFjaykge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihmZWVkRm9yd2FyZCwgZmVlZGJhY2spO1xuICAgIH1cbiAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgIH1cbiAgICBjcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcsIGNvbnN0cmFpbnRzKTtcbiAgICB9XG4gICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShlbGVtZW50KSB7XG4gICAgICAgIGFzc2VydChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSwgXCJOb3QgYXZhaWxhYmxlIGlmIE9mZmxpbmVBdWRpb0NvbnRleHRcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoZWxlbWVudCk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKSB7XG4gICAgICAgIGFzc2VydChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSwgXCJOb3QgYXZhaWxhYmxlIGlmIE9mZmxpbmVBdWRpb0NvbnRleHRcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgfVxuICAgIGRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdGVuZXJcbiAgICAgKi9cbiAgICBnZXQgbGlzdGVuZXIoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbGlzdGVuZXI7XG4gICAgfVxuICAgIHNldCBsaXN0ZW5lcihsKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiVGhlIGxpc3RlbmVyIGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl9saXN0ZW5lciA9IGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZXJlIGlzIG9ubHkgb25lIFRyYW5zcG9ydCBwZXIgQ29udGV4dC4gSXQgaXMgY3JlYXRlZCBvbiBpbml0aWFsaXphdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgdHJhbnNwb3J0KCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydDtcbiAgICB9XG4gICAgc2V0IHRyYW5zcG9ydCh0KSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiVGhlIHRyYW5zcG9ydCBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBpcyB0aGUgRHJhdyBvYmplY3QgZm9yIHRoZSBjb250ZXh0IHdoaWNoIGlzIHVzZWZ1bCBmb3Igc3luY2hyb25pemluZyB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUb25lLmpzIGNsb2NrLlxuICAgICAqL1xuICAgIGdldCBkcmF3KCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyYXc7XG4gICAgfVxuICAgIHNldCBkcmF3KGQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJEcmF3IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl9kcmF3ID0gZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIENvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqL1xuICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXN0aW5hdGlvbjtcbiAgICB9XG4gICAgc2V0IGRlc3RpbmF0aW9uKGQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgZGVzdGluYXRpb24gY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2Rlc3RpbmF0aW9uID0gZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIGF1ZGlvIHdvcmtsZXQgbm9kZSBmcm9tIGEgbmFtZSBhbmQgb3B0aW9ucy4gVGhlIG1vZHVsZVxuICAgICAqIG11c3QgZmlyc3QgYmUgbG9hZGVkIHVzaW5nIFtbYWRkQXVkaW9Xb3JrbGV0TW9kdWxlXV0uXG4gICAgICovXG4gICAgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKHRoaXMucmF3Q29udGV4dCwgbmFtZSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgbW9kdWxlXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBtb2R1bGVcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlXG4gICAgICovXG4gICAgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKHVybCwgbmFtZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZCh0aGlzLnJhd0NvbnRleHQuYXVkaW9Xb3JrbGV0KSwgXCJBdWRpb1dvcmtsZXROb2RlIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgc2VjdXJlIGNvbnRleHQgKGh0dHBzIG9yIGxvY2FsaG9zdClcIik7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dvcmtsZXRNb2R1bGVzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXRNb2R1bGVzLnNldChuYW1lLCB0aGlzLnJhd0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSh1cmwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHlpZWxkIHRoaXMuX3dvcmtsZXRNb2R1bGVzLmdldChuYW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gYWxsIG9mIHRoZSB3b3JrbGV0cyBoYXZlIGJlZW4gbG9hZGVkIG9uIHRoaXMgY29udGV4dFxuICAgICAqL1xuICAgIHdvcmtsZXRzQXJlUmVhZHkoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMuZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZXMucHVzaChwcm9taXNlKSk7XG4gICAgICAgICAgICB5aWVsZCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRJQ0tFUlxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogSG93IG9mdGVuIHRoZSBpbnRlcnZhbCBjYWxsYmFjayBpcyBpbnZva2VkLlxuICAgICAqIFRoaXMgbnVtYmVyIGNvcnJlc3BvbmRzIHRvIGhvdyByZXNwb25zaXZlIHRoZSBzY2hlZHVsaW5nXG4gICAgICogY2FuIGJlLiBjb250ZXh0LnVwZGF0ZUludGVydmFsICsgY29udGV4dC5sb29rQWhlYWQgZ2l2ZXMgeW91IHRoZVxuICAgICAqIHRvdGFsIGxhdGVuY3kgYmV0d2VlbiBzY2hlZHVsaW5nIGFuIGV2ZW50IGFuZCBoZWFyaW5nIGl0LlxuICAgICAqL1xuICAgIGdldCB1cGRhdGVJbnRlcnZhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tlci51cGRhdGVJbnRlcnZhbDtcbiAgICB9XG4gICAgc2V0IHVwZGF0ZUludGVydmFsKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX3RpY2tlci51cGRhdGVJbnRlcnZhbCA9IGludGVydmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGF0IHRoZSBzb3VyY2Ugb2YgdGhlIGNsb2NrIGlzLCBlaXRoZXIgXCJ3b3JrZXJcIiAoZGVmYXVsdCksXG4gICAgICogXCJ0aW1lb3V0XCIsIG9yIFwib2ZmbGluZVwiIChub25lKS5cbiAgICAgKi9cbiAgICBnZXQgY2xvY2tTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IGNsb2NrU291cmNlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdGlja2VyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBwbGF5YmFjaywgd2hpY2ggYWZmZWN0cyB0cmFkZW9mZnMgYmV0d2VlbiBhdWRpb1xuICAgICAqIG91dHB1dCBsYXRlbmN5IGFuZCByZXNwb25zaXZlbmVzcy5cbiAgICAgKiBJbiBhZGRpdGlvbiB0byBzZXR0aW5nIHRoZSB2YWx1ZSBpbiBzZWNvbmRzLCB0aGUgbGF0ZW5jeUhpbnQgYWxzb1xuICAgICAqIGFjY2VwdHMgdGhlIHN0cmluZ3MgXCJpbnRlcmFjdGl2ZVwiIChwcmlvcml0aXplcyBsb3cgbGF0ZW5jeSksXG4gICAgICogXCJwbGF5YmFja1wiIChwcmlvcml0aXplcyBzdXN0YWluZWQgcGxheWJhY2spLCBcImJhbGFuY2VkXCIgKGJhbGFuY2VzXG4gICAgICogbGF0ZW5jeSBhbmQgcGVyZm9ybWFuY2UpLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gcHJpb3JpdGl6ZSBzdXN0YWluZWQgcGxheWJhY2tcbiAgICAgKiBjb25zdCBjb250ZXh0ID0gbmV3IFRvbmUuQ29udGV4dCh7IGxhdGVuY3lIaW50OiBcInBsYXliYWNrXCIgfSk7XG4gICAgICogLy8gc2V0IHRoaXMgY29udGV4dCBhcyB0aGUgZ2xvYmFsIENvbnRleHRcbiAgICAgKiBUb25lLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICogLy8gdGhlIGdsb2JhbCBjb250ZXh0IGlzIGdldHRhYmxlIHdpdGggVG9uZS5nZXRDb250ZXh0KClcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLmdldENvbnRleHQoKS5sYXRlbmN5SGludCk7XG4gICAgICovXG4gICAgZ2V0IGxhdGVuY3lIaW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGF0ZW5jeUhpbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgbG9va0FoZWFkIGFuZCB1cGRhdGVJbnRlcnZhbCBiYXNlZCBvbiB0aGUgbGF0ZW5jeUhpbnRcbiAgICAgKi9cbiAgICBfc2V0TGF0ZW5jeUhpbnQoaGludCkge1xuICAgICAgICBsZXQgbG9va0FoZWFkVmFsdWUgPSAwO1xuICAgICAgICB0aGlzLl9sYXRlbmN5SGludCA9IGhpbnQ7XG4gICAgICAgIGlmIChpc1N0cmluZyhoaW50KSkge1xuICAgICAgICAgICAgc3dpdGNoIChoaW50KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcImludGVyYWN0aXZlXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC4xO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwicGxheWJhY2tcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJiYWxhbmNlZFwiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuMjU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gbG9va0FoZWFkVmFsdWU7XG4gICAgICAgIHRoaXMudXBkYXRlSW50ZXJ2YWwgPSBsb29rQWhlYWRWYWx1ZSAvIDI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB1bndyYXBwZWQgQXVkaW9Db250ZXh0IG9yIE9mZmxpbmVBdWRpb0NvbnRleHRcbiAgICAgKi9cbiAgICBnZXQgcmF3Q29udGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBwbHVzIGEgc2hvcnQgW1tsb29rQWhlYWRdXS5cbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmN1cnJlbnRUaW1lICsgdGhpcy5sb29rQWhlYWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSB3aXRob3V0IHRoZSBbW2xvb2tBaGVhZF1dLlxuICAgICAqIEluIG1vc3QgY2FzZXMgaXQgaXMgYmV0dGVyIHRvIHVzZSBbW25vd11dIGluc3RlYWQgb2YgW1tpbW1lZGlhdGVdXSBzaW5jZVxuICAgICAqIHdpdGggW1tub3ddXSB0aGUgW1tsb29rQWhlYWRdXSBpcyBhcHBsaWVkIGVxdWFsbHkgdG8gX2FsbF8gY29tcG9uZW50cyBpbmNsdWRpbmcgaW50ZXJuYWwgY29tcG9uZW50cyxcbiAgICAgKiB0byBtYWtpbmcgc3VyZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgc2NoZWR1bGVkIGluIHN5bmMuIE1peGluZyBbW25vd11dIGFuZCBbW2ltbWVkaWF0ZV1dXG4gICAgICogY2FuIGNhdXNlIHNvbWUgdGltaW5nIGlzc3Vlcy4gSWYgbm8gbG9va0FoZWFkIGlzIGRlc2lyZWQsIHlvdSBjYW4gc2V0IHRoZSBbW2xvb2tBaGVhZF1dIHRvIGAwYC5cbiAgICAgKi9cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydHMgdGhlIGF1ZGlvIGNvbnRleHQgZnJvbSBhIHN1c3BlbmRlZCBzdGF0ZS4gVGhpcyBpcyByZXF1aXJlZFxuICAgICAqIHRvIGluaXRpYWxseSBzdGFydCB0aGUgQXVkaW9Db250ZXh0LiBTZWUgW1tUb25lLnN0YXJ0XV1cbiAgICAgKi9cbiAgICByZXN1bWUoKSB7XG4gICAgICAgIGlmIChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQucmVzdW1lKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIGNvbnRleHQuIE9uY2UgY2xvc2VkLCB0aGUgY29udGV4dCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgYW5kXG4gICAgICogYW55IEF1ZGlvTm9kZXMgY3JlYXRlZCBmcm9tIHRoZSBjb250ZXh0IHdpbGwgYmUgc2lsZW50LlxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgaWYgKGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgdGhpcy5fY29udGV4dC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgY2xvc2VDb250ZXh0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKipJbnRlcm5hbCoqIEdlbmVyYXRlIGEgbG9vcGVkIGJ1ZmZlciBhdCBzb21lIGNvbnN0YW50IHZhbHVlLlxuICAgICAqL1xuICAgIGdldENvbnN0YW50KHZhbCkge1xuICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRzLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29uc3RhbnRzLmdldCh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMTI4LCB0aGlzLl9jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3QgYXJyID0gYnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb25zdGFudCA9IHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgICAgICBjb25zdGFudC5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICAgICAgY29uc3RhbnQuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgICAgIGNvbnN0YW50LmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0YW50Lmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3RhbnQuc3RhcnQoMCk7XG4gICAgICAgICAgICB0aGlzLl9jb25zdGFudHMuc2V0KHZhbCwgY29uc3RhbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLiBBbHNvIGNsb3NlcyB0aGUgYXVkaW8gY29udGV4dC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpY2tlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmRpc3Bvc2UoKTtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5fY29uc3RhbnRzKS5tYXAoKHZhbCkgPT4gdGhpcy5fY29uc3RhbnRzW3ZhbF0uZGlzY29ubmVjdCgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVElNRU9VVFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRoZSBwcml2YXRlIGxvb3Agd2hpY2gga2VlcHMgdHJhY2sgb2YgdGhlIGNvbnRleHQgc2NoZWR1bGVkIHRpbWVvdXRzXG4gICAgICogSXMgaW52b2tlZCBmcm9tIHRoZSBjbG9jayBzb3VyY2VcbiAgICAgKi9cbiAgICBfdGltZW91dExvb3AoKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGxldCBmaXJzdEV2ZW50ID0gdGhpcy5fdGltZW91dHMucGVlaygpO1xuICAgICAgICB3aGlsZSAodGhpcy5fdGltZW91dHMubGVuZ3RoICYmIGZpcnN0RXZlbnQgJiYgZmlyc3RFdmVudC50aW1lIDw9IG5vdykge1xuICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgZmlyc3RFdmVudC5jYWxsYmFjaygpO1xuICAgICAgICAgICAgLy8gc2hpZnQgdGhlIGZpcnN0IGV2ZW50IG9mZlxuICAgICAgICAgICAgdGhpcy5fdGltZW91dHMuc2hpZnQoKTtcbiAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCBvbmVcbiAgICAgICAgICAgIGZpcnN0RXZlbnQgPSB0aGlzLl90aW1lb3V0cy5wZWVrKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBzZXRUaW1lb3V0IHdoaWNoIGlzIGd1YXJhbnRlZWQgYnkgdGhlIGNsb2NrIHNvdXJjZS5cbiAgICAgKiBBbHNvIHJ1bnMgaW4gdGhlIG9mZmxpbmUgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gIGZuICAgICAgIFRoZSBjYWxsYmFjayB0byBpbnZva2VcbiAgICAgKiBAcGFyYW0gIHRpbWVvdXQgIFRoZSB0aW1lb3V0IGluIHNlY29uZHNcbiAgICAgKiBAcmV0dXJucyBJRCB0byB1c2Ugd2hlbiBpbnZva2luZyBDb250ZXh0LmNsZWFyVGltZW91dFxuICAgICAqL1xuICAgIHNldFRpbWVvdXQoZm4sIHRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dElkcysrO1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuICAgICAgICAgICAgY2FsbGJhY2s6IGZuLFxuICAgICAgICAgICAgaWQ6IHRoaXMuX3RpbWVvdXRJZHMsXG4gICAgICAgICAgICB0aW1lOiBub3cgKyB0aW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVvdXRJZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFycyBhIHByZXZpb3VzbHkgc2NoZWR1bGVkIHRpbWVvdXQgd2l0aCBUb25lLmNvbnRleHQuc2V0VGltZW91dFxuICAgICAqIEBwYXJhbSAgaWQgIFRoZSBJRCByZXR1cm5lZCBmcm9tIHNldFRpbWVvdXRcbiAgICAgKi9cbiAgICBjbGVhclRpbWVvdXQoaWQpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5yZW1vdmUoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBmdW5jdGlvbiBzY2hlZHVsZWQgYnkgW1tzZXRJbnRlcnZhbF1dXG4gICAgICovXG4gICAgY2xlYXJJbnRlcnZhbChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jbGVhclRpbWVvdXQoaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcmVwZWF0aW5nIGV2ZW50IHRvIHRoZSBjb250ZXh0J3MgY2FsbGJhY2sgY2xvY2tcbiAgICAgKi9cbiAgICBzZXRJbnRlcnZhbChmbiwgaW50ZXJ2YWwpIHtcbiAgICAgICAgY29uc3QgaWQgPSArK3RoaXMuX3RpbWVvdXRJZHM7XG4gICAgICAgIGNvbnN0IGludGVydmFsRm4gPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgdGhpcy5fdGltZW91dHMuYWRkKHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgZXZlbnQgdG8gcmVwZWF0IGl0XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsRm4oKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHRpbWU6IG5vdyArIGludGVydmFsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGtpY2sgaXQgb2ZmXG4gICAgICAgIGludGVydmFsRm4oKTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBCYXNlQ29udGV4dCB9IGZyb20gXCIuL0Jhc2VDb250ZXh0XCI7XG5leHBvcnQgY2xhc3MgRHVtbXlDb250ZXh0IGV4dGVuZHMgQmFzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmxvb2tBaGVhZCA9IDA7XG4gICAgICAgIHRoaXMubGF0ZW5jeUhpbnQgPSAwO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IGZhbHNlO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJBU0UgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyKF9udW1iZXJPZkNoYW5uZWxzLCBfbGVuZ3RoLCBfc2FtcGxlUmF0ZSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIoX251bWJlck9mSW5wdXRzKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKF9udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlRGVsYXkoX21heERlbGF5VGltZSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVHYWluKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUlJUkZpbHRlcihfZmVlZEZvcndhcmQsIF9mZWVkYmFjaykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVQZXJpb2RpY1dhdmUoX3JlYWwsIF9pbWFnLCBfY29uc3RyYWludHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShfc3RyZWFtKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKF9lbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBkZWNvZGVBdWRpb0RhdGEoX2F1ZGlvRGF0YSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUT05FIEFVRElPIENPTlRFWFQgTUVUSE9EU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShfbmFtZSwgX29wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgcmF3Q29udGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUoX3VybCwgX25hbWUpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlc3VtZSgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBzZXRUaW1lb3V0KF9mbiwgX3RpbWVvdXQpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNsZWFyVGltZW91dChfaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldEludGVydmFsKF9mbiwgX2ludGVydmFsKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjbGVhckludGVydmFsKF9pZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0Q29uc3RhbnQoX3ZhbCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgdHJhbnNwb3J0KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBkcmF3KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHNldCBkcmF3KF9kKSB7IH1cbiAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgc2V0IGRlc3RpbmF0aW9uKF9kKSB7IH1cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUR1bW15Q29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIE1ha2UgdGhlIHByb3BlcnR5IG5vdCB3cml0YWJsZSB1c2luZyBgZGVmaW5lUHJvcGVydHlgLiBJbnRlcm5hbCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRPbmx5KHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBpZiAoaXNBcnJheShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvcGVydHkuZm9yRWFjaChzdHIgPT4gcmVhZE9ubHkodGFyZ2V0LCBzdHIpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2UgYW4gYXR0cmlidXRlIHdyaXRlYWJsZS4gSW50ZXJuYWwgdXNlIG9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0YWJsZSh0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XG4gICAgICAgIHByb3BlcnR5LmZvckVhY2goc3RyID0+IHdyaXRhYmxlKHRhcmdldCwgc3RyKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwge1xuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBub09wID0gKCkgPT4ge1xuICAgIC8vIG5vIG9wZXJhdGlvbiBoZXJlIVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUludGVyZmFjZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOdW1iZXIsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBdWRpb0J1ZmZlciBsb2FkaW5nIGFuZCBzdG9yYWdlLiBUb25lQXVkaW9CdWZmZXIgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IGFsbFxuICogY2xhc3NlcyB0aGF0IG1ha2UgcmVxdWVzdHMgZm9yIGF1ZGlvIGZpbGVzIHN1Y2ggYXMgVG9uZS5QbGF5ZXIsXG4gKiBUb25lLlNhbXBsZXIgYW5kIFRvbmUuQ29udm9sdmVyLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGJ1ZmZlciA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMS5tcDNcIiwgKCkgPT4ge1xuICogXHRjb25zb2xlLmxvZyhcImxvYWRlZFwiKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb0J1ZmZlciBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb0J1ZmZlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25sb2FkID0gbm9PcDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVBdWRpb0J1ZmZlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiLCBcIm9uZXJyb3JcIl0pO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSBvcHRpb25zLnJldmVyc2U7XG4gICAgICAgIHRoaXMub25sb2FkID0gb3B0aW9ucy5vbmxvYWQ7XG4gICAgICAgIGlmIChvcHRpb25zLnVybCAmJiBpc0F1ZGlvQnVmZmVyKG9wdGlvbnMudXJsKSB8fCBvcHRpb25zLnVybCBpbnN0YW5jZW9mIFRvbmVBdWRpb0J1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5zZXQob3B0aW9ucy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKG9wdGlvbnMudXJsKSkge1xuICAgICAgICAgICAgLy8gaW5pdGlhdGUgdGhlIGRvd25sb2FkXG4gICAgICAgICAgICB0aGlzLmxvYWQob3B0aW9ucy51cmwpLmNhdGNoKG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2FtcGxlIHJhdGUgb2YgdGhlIEF1ZGlvQnVmZmVyXG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRDb250ZXh0KCkuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXNzIGluIGFuIEF1ZGlvQnVmZmVyIG9yIFRvbmVBdWRpb0J1ZmZlciB0byBzZXQgdGhlIHZhbHVlIG9mIHRoaXMgYnVmZmVyLlxuICAgICAqL1xuICAgIHNldChidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFRvbmVBdWRpb0J1ZmZlcikge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBsb2FkZWQsIHNldCBpdFxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXIuZ2V0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2Ugd2hlbiBpdCdzIGxvYWRlZCwgaW52b2tlIGl0J3MgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICBidWZmZXIub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldChidWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ubG9hZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJldmVyc2UgaXQgaW5pdGlhbGx5XG4gICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCkge1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIHN0b3JlZCBpbiB0aGUgb2JqZWN0LlxuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZXMgYW4gZmV0Y2ggcmVxdWVzdCBmb3IgdGhlIHNlbGVjdGVkIHVybCB0aGVuIGRlY29kZXMgdGhlIGZpbGUgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIEludm9rZXMgdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBmaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhpcyBUb25lQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgZG9uZUxvYWRpbmcgPSBUb25lQXVkaW9CdWZmZXIubG9hZCh1cmwpLnRoZW4oYXVkaW9CdWZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0KGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAvLyBpbnZva2UgdGhlIG9ubG9hZCBtZXRob2RcbiAgICAgICAgICAgICAgICB0aGlzLm9ubG9hZCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5wdXNoKGRvbmVMb2FkaW5nKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgeWllbGQgZG9uZUxvYWRpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIGRvd25sb2FkZWQgZmlsZVxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5pbmRleE9mKGRvbmVMb2FkaW5nKTtcbiAgICAgICAgICAgICAgICBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF1ZGlvIGJ1ZmZlciBmcm9tIHRoZSBhcnJheS5cbiAgICAgKiBUbyBjcmVhdGUgYSBtdWx0aWNoYW5uZWwgQXVkaW9CdWZmZXIsIHBhc3MgaW4gYSBtdWx0aWRpbWVuc2lvbmFsIGFycmF5LlxuICAgICAqIEBwYXJhbSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbCB0aGUgYXVkaW8gYnVmZmVyXG4gICAgICovXG4gICAgZnJvbUFycmF5KGFycmF5KSB7XG4gICAgICAgIGNvbnN0IGlzTXVsdGlkaW1lbnNpb25hbCA9IGlzQXJyYXkoYXJyYXkpICYmIGFycmF5WzBdLmxlbmd0aCA+IDA7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gaXNNdWx0aWRpbWVuc2lvbmFsID8gYXJyYXkubGVuZ3RoIDogMTtcbiAgICAgICAgY29uc3QgbGVuID0gaXNNdWx0aWRpbWVuc2lvbmFsID8gYXJyYXlbMF0ubGVuZ3RoIDogYXJyYXkubGVuZ3RoO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0LmNyZWF0ZUJ1ZmZlcihjaGFubmVscywgbGVuLCBjb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBtdWx0aUNoYW5uZWxBcnJheSA9ICFpc011bHRpZGltZW5zaW9uYWwgJiYgY2hhbm5lbHMgPT09IDEgP1xuICAgICAgICAgICAgW2FycmF5XSA6IGFycmF5O1xuICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNoYW5uZWxzOyBjKyspIHtcbiAgICAgICAgICAgIGJ1ZmZlci5jb3B5VG9DaGFubmVsKG11bHRpQ2hhbm5lbEFycmF5W2NdLCBjKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdW1zIG11bHRpcGxlIGNoYW5uZWxzIGludG8gMSBjaGFubmVsXG4gICAgICogQHBhcmFtIGNoYW5OdW0gT3B0aW9uYWxseSBvbmx5IGNvcHkgYSBzaW5nbGUgY2hhbm5lbCBmcm9tIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICB0b01vbm8oY2hhbk51bSkge1xuICAgICAgICBpZiAoaXNOdW1iZXIoY2hhbk51bSkpIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbUFycmF5KHRoaXMudG9BcnJheShjaGFuTnVtKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgb3V0cHV0QXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IG51bUNoYW5uZWxzID0gdGhpcy5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBudW1DaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbEFycmF5ID0gdGhpcy50b0FycmF5KGNoYW5uZWwpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dEFycmF5W2ldICs9IGNoYW5uZWxBcnJheVtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBkaXZpZGUgYnkgdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAgICAgICAgb3V0cHV0QXJyYXkgPSBvdXRwdXRBcnJheS5tYXAoc2FtcGxlID0+IHNhbXBsZSAvIG51bUNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuZnJvbUFycmF5KG91dHB1dEFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidWZmZXIgYXMgYW4gYXJyYXkuIFNpbmdsZSBjaGFubmVsIGJ1ZmZlcnMgd2lsbCByZXR1cm4gYSAxLWRpbWVuc2lvbmFsXG4gICAgICogRmxvYXQzMkFycmF5LCBhbmQgbXVsdGljaGFubmVsIGJ1ZmZlcnMgd2lsbCByZXR1cm4gbXVsdGlkaW1lbnNpb25hbCBhcnJheXMuXG4gICAgICogQHBhcmFtIGNoYW5uZWwgT3B0aW9uYWxseSBvbmx5IGNvcHkgYSBzaW5nbGUgY2hhbm5lbCBmcm9tIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICB0b0FycmF5KGNoYW5uZWwpIHtcbiAgICAgICAgaWYgKGlzTnVtYmVyKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRDaGFubmVsRGF0YShjaGFubmVsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLm51bWJlck9mQ2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQXJyYXkoMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgdGhpcy5udW1iZXJPZkNoYW5uZWxzOyBjKyspIHtcbiAgICAgICAgICAgICAgICByZXRbY10gPSB0aGlzLmdldENoYW5uZWxEYXRhKGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBGbG9hdDMyQXJyYXkgcmVwcmVzZW50aW5nIHRoZSBQQ00gYXVkaW8gZGF0YSBmb3IgdGhlIHNwZWNpZmljIGNoYW5uZWwuXG4gICAgICogQHBhcmFtICBjaGFubmVsICBUaGUgY2hhbm5lbCBudW1iZXIgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgYXVkaW8gYXMgYSBUeXBlZEFycmF5XG4gICAgICovXG4gICAgZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3V0IGEgc3Vic2VjdGlvbiBvZiB0aGUgYXJyYXkgYW5kIHJldHVybiBhIGJ1ZmZlciBvZiB0aGVcbiAgICAgKiBzdWJzZWN0aW9uLiBEb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGJ1ZmZlclxuICAgICAqIEBwYXJhbSBzdGFydCBUaGUgdGltZSB0byBzdGFydCB0aGUgc2xpY2VcbiAgICAgKiBAcGFyYW0gZW5kIFRoZSBlbmQgdGltZSB0byBzbGljZS4gSWYgbm9uZSBpcyBnaXZlbiB3aWxsIGRlZmF1bHQgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gICAgICovXG4gICAgc2xpY2Uoc3RhcnQsIGVuZCA9IHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgY29uc3Qgc3RhcnRTYW1wbGVzID0gTWF0aC5mbG9vcihzdGFydCAqIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGVuZFNhbXBsZXMgPSBNYXRoLmZsb29yKGVuZCAqIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGFzc2VydChzdGFydFNhbXBsZXMgPCBlbmRTYW1wbGVzLCBcIlRoZSBzdGFydCB0aW1lIG11c3QgYmUgbGVzcyB0aGFuIHRoZSBlbmQgdGltZVwiKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gZW5kU2FtcGxlcyAtIHN0YXJ0U2FtcGxlcztcbiAgICAgICAgY29uc3QgcmV0QnVmZmVyID0gZ2V0Q29udGV4dCgpLmNyZWF0ZUJ1ZmZlcih0aGlzLm51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgZm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICAgICAgcmV0QnVmZmVyLmNvcHlUb0NoYW5uZWwodGhpcy5nZXRDaGFubmVsRGF0YShjaGFubmVsKS5zdWJhcnJheShzdGFydFNhbXBsZXMsIGVuZFNhbXBsZXMpLCBjaGFubmVsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFRvbmVBdWRpb0J1ZmZlcihyZXRCdWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgX3JldmVyc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLmxvYWRlZCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2hhbm5lbERhdGEoaSkucmV2ZXJzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIGlzIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlciBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIGdldCBkdXJhdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlciBpbiBzYW1wbGVzXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRpc2NyZXRlIGF1ZGlvIGNoYW5uZWxzLiBSZXR1cm5zIDAgaWYgbm8gYnVmZmVyIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZDaGFubmVscygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV2ZXJzZSB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmV2ZXJzZWQ7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICBpZiAodGhpcy5fcmV2ZXJzZWQgIT09IHJldikge1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZWQgPSByZXY7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgVG9uZUF1ZGlvQnVmZmVyIGZyb20gdGhlIGFycmF5LiBUbyBjcmVhdGUgYSBtdWx0aWNoYW5uZWwgQXVkaW9CdWZmZXIsXG4gICAgICogcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcbiAgICAgKiBAcmV0dXJuIEEgVG9uZUF1ZGlvQnVmZmVyIGNyZWF0ZWQgZnJvbSB0aGUgYXJyYXlcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUFycmF5KGFycmF5KSB7XG4gICAgICAgIHJldHVybiAobmV3IFRvbmVBdWRpb0J1ZmZlcigpKS5mcm9tQXJyYXkoYXJyYXkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVG9uZUF1ZGlvQnVmZmVyIGZyb20gYSBVUkwsIHJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIGEgVG9uZUF1ZGlvQnVmZmVyXG4gICAgICogQHBhcmFtICB1cmwgVGhlIHVybCB0byBsb2FkLlxuICAgICAqIEByZXR1cm4gQSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIGEgVG9uZUF1ZGlvQnVmZmVyXG4gICAgICovXG4gICAgc3RhdGljIGZyb21VcmwodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWRzIGEgdXJsIHVzaW5nIGZldGNoIGFuZCByZXR1cm5zIHRoZSBBdWRpb0J1ZmZlci5cbiAgICAgKi9cbiAgICBzdGF0aWMgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIC8vIHRlc3QgaWYgdGhlIHVybCBjb250YWlucyBtdWx0aXBsZSBleHRlbnNpb25zXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gdXJsLm1hdGNoKC9cXFsoW15cXF1cXFtdK1xcfC4rKVxcXSQvKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IG1hdGNoZXNbMV0uc3BsaXQoXCJ8XCIpO1xuICAgICAgICAgICAgICAgIGxldCBleHRlbnNpb24gPSBleHRlbnNpb25zWzBdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZXh0IG9mIGV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uID0gZXh0O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UobWF0Y2hlc1swXSwgZXh0ZW5zaW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGVyZSBpcyBhIHNsYXNoIGJldHdlZW4gdGhlIGJhc2VVcmwgYW5kIHRoZSB1cmxcbiAgICAgICAgICAgIGNvbnN0IGJhc2VVcmwgPSBUb25lQXVkaW9CdWZmZXIuYmFzZVVybCA9PT0gXCJcIiB8fCBUb25lQXVkaW9CdWZmZXIuYmFzZVVybC5lbmRzV2l0aChcIi9cIikgPyBUb25lQXVkaW9CdWZmZXIuYmFzZVVybCA6IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsICsgXCIvXCI7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHlpZWxkIGZldGNoKGJhc2VVcmwgKyB1cmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgY291bGQgbm90IGxvYWQgdXJsOiAke3VybH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0geWllbGQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0geWllbGQgZ2V0Q29udGV4dCgpLmRlY29kZUF1ZGlvRGF0YShhcnJheUJ1ZmZlcik7XG4gICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDaGVja3MgYSB1cmwncyBleHRlbnNpb24gdG8gc2VlIGlmIHRoZSBjdXJyZW50IGJyb3dzZXIgY2FuIHBsYXkgdGhhdCBmaWxlIHR5cGUuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsL2V4dGVuc2lvbiB0byB0ZXN0XG4gICAgICogQHJldHVybiBJZiB0aGUgZmlsZSBleHRlbnNpb24gY2FuIGJlIHBsYXllZFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShcIndhdlwiKTsgLy8gcmV0dXJucyB0cnVlXG4gICAgICogVG9uZS5Ub25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKFwicGF0aC90by9maWxlLndhdlwiKTsgLy8gcmV0dXJucyB0cnVlXG4gICAgICovXG4gICAgc3RhdGljIHN1cHBvcnRzVHlwZSh1cmwpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IHVybC5zcGxpdChcIi5cIik7XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbZXh0ZW5zaW9ucy5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYXVkaW9cIikuY2FuUGxheVR5cGUoXCJhdWRpby9cIiArIGV4dGVuc2lvbik7XG4gICAgICAgIHJldHVybiByZXNwb25zZSAhPT0gXCJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGJ1ZmZlcnMgaGF2ZSBsb2FkZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gdGhpcyBtYWtlcyBzdXJlIHRoYXQgdGhlIGZ1bmN0aW9uIGlzIGFsd2F5cyBhc3luY1xuICAgICAgICAgICAgeWllbGQgUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB3aGlsZSAoVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFNUQVRJQyBNRVRIT0RTXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogQSBwYXRoIHdoaWNoIGlzIHByZWZpeGVkIGJlZm9yZSBldmVyeSB1cmwuXG4gKi9cblRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsID0gXCJcIjtcbi8qKlxuICogQWxsIG9mIHRoZSBkb3dubG9hZHNcbiAqL1xuVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2FkcyA9IFtdO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvQnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRcIjtcbmltcG9ydCB7IGlzT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogLy8gZ2VuZXJhdGUgYSBzaW5nbGUgY2hhbm5lbCwgMC41IHNlY29uZCBidWZmZXJcbiAqIGNvbnN0IGNvbnRleHQgPSBuZXcgVG9uZS5PZmZsaW5lQ29udGV4dCgxLCAwLjUsIDQ0MTAwKTtcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoeyBjb250ZXh0IH0pO1xuICogY29udGV4dC5yZW5kZXIoKS50aGVuKGJ1ZmZlciA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzLCBidWZmZXIuZHVyYXRpb24pO1xuICogfSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBPZmZsaW5lQ29udGV4dCBleHRlbmRzIENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcih7XG4gICAgICAgICAgICBjbG9ja1NvdXJjZTogXCJvZmZsaW5lXCIsXG4gICAgICAgICAgICBjb250ZXh0OiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdIDogY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSAqIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzJdKSxcbiAgICAgICAgICAgIGxvb2tBaGVhZDogMCxcbiAgICAgICAgICAgIHVwZGF0ZUludGVydmFsOiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICAgICAgMTI4IC8gYXJndW1lbnRzWzBdLnNhbXBsZVJhdGUgOiAxMjggLyBhcmd1bWVudHNbMl0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9mZmxpbmVDb250ZXh0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBhcnRpZmljaWFsIGNsb2NrIHNvdXJjZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgPSAwO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IHRydWU7XG4gICAgICAgIHRoaXMuX2R1cmF0aW9uID0gaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSkgP1xuICAgICAgICAgICAgYXJndW1lbnRzWzBdLmxlbmd0aCAvIGFyZ3VtZW50c1swXS5zYW1wbGVSYXRlIDogYXJndW1lbnRzWzFdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSB0aGUgbm93IG1ldGhvZCB0byBwb2ludCB0byB0aGUgaW50ZXJuYWwgY2xvY2sgdGltZVxuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTYW1lIGFzIHRoaXMubm93KClcbiAgICAgKi9cbiAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGp1c3QgdGhlIGNsb2NrIHBvcnRpb24gb2YgdGhlIGF1ZGlvIGNvbnRleHQuXG4gICAgICovXG4gICAgX3JlbmRlckNsb2NrKGFzeW5jaHJvbm91cykge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgICAgICAgIHdoaWxlICh0aGlzLl9kdXJhdGlvbiAtIHRoaXMuX2N1cnJlbnRUaW1lID49IDApIHtcbiAgICAgICAgICAgICAgICAvLyBpbnZva2UgYWxsIHRoZSBjYWxsYmFja3Mgb24gdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwidGlja1wiKTtcbiAgICAgICAgICAgICAgICAvLyBpbmNyZW1lbnQgdGhlIGNsb2NrIGluIGJsb2NrLXNpemVkIGNodW5rc1xuICAgICAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRUaW1lICs9IDEyOCAvIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAvLyB5aWVsZCBvbmNlIGEgc2Vjb25kIG9mIGF1ZGlvXG4gICAgICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgICAgICBjb25zdCB5aWVsZEV2ZXJ5ID0gTWF0aC5mbG9vcih0aGlzLnNhbXBsZVJhdGUgLyAxMjgpO1xuICAgICAgICAgICAgICAgIGlmIChhc3luY2hyb25vdXMgJiYgaW5kZXggJSB5aWVsZEV2ZXJ5ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIG5ldyBQcm9taXNlKGRvbmUgPT4gc2V0VGltZW91dChkb25lLCAxKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHRoZSBvdXRwdXQgb2YgdGhlIE9mZmxpbmVDb250ZXh0XG4gICAgICogQHBhcmFtIGFzeW5jaHJvbm91cyBJZiB0aGUgY2xvY2sgc2hvdWxkIGJlIHJlbmRlcmVkIGFzeW5jaHJvbm91c2x5LCB3aGljaCB3aWxsIG5vdCBibG9jayB0aGUgbWFpbiB0aHJlYWQsIGJ1dCBiZSBzbGlnaHRseSBzbG93ZXIuXG4gICAgICovXG4gICAgcmVuZGVyKGFzeW5jaHJvbm91cyA9IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHlpZWxkIHRoaXMud29ya2xldHNBcmVSZWFkeSgpO1xuICAgICAgICAgICAgeWllbGQgdGhpcy5fcmVuZGVyQ2xvY2soYXN5bmNocm9ub3VzKTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIHRoaXMuX2NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKGJ1ZmZlcik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY29udGV4dFxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T2ZmbGluZUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gXCIuLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyBoYXNBdWRpb0NvbnRleHQsIHRoZVdpbmRvdyB9IGZyb20gXCIuL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4vY29udGV4dC9Db250ZXh0XCI7XG5pbXBvcnQgeyBEdW1teUNvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L0R1bW15Q29udGV4dFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBpc0F1ZGlvQ29udGV4dCwgaXNPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuLyoqXG4gKiBUaGlzIGR1bW15IGNvbnRleHQgaXMgdXNlZCB0byBhdm9pZCB0aHJvd2luZyBpbW1lZGlhdGUgZXJyb3JzIHdoZW4gaW1wb3J0aW5nIGluIE5vZGUuanNcbiAqL1xuY29uc3QgZHVtbXlDb250ZXh0ID0gbmV3IER1bW15Q29udGV4dCgpO1xuLyoqXG4gKiBUaGUgZ2xvYmFsIGF1ZGlvIGNvbnRleHQgd2hpY2ggaXMgZ2V0YWJsZSBhbmQgYXNzaWduYWJsZSB0aHJvdWdoXG4gKiBnZXRDb250ZXh0IGFuZCBzZXRDb250ZXh0XG4gKi9cbmxldCBnbG9iYWxDb250ZXh0ID0gZHVtbXlDb250ZXh0O1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN5c3RlbS13aWRlIFtbQ29udGV4dF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICBpZiAoZ2xvYmFsQ29udGV4dCA9PT0gZHVtbXlDb250ZXh0ICYmIGhhc0F1ZGlvQ29udGV4dCkge1xuICAgICAgICBzZXRDb250ZXh0KG5ldyBDb250ZXh0KCkpO1xuICAgIH1cbiAgICByZXR1cm4gZ2xvYmFsQ29udGV4dDtcbn1cbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IGF1ZGlvIGNvbnRleHRcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRDb250ZXh0KGNvbnRleHQpIHtcbiAgICBpZiAoaXNBdWRpb0NvbnRleHQoY29udGV4dCkpIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IG5ldyBDb250ZXh0KGNvbnRleHQpO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc09mZmxpbmVBdWRpb0NvbnRleHQoY29udGV4dCkpIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dChjb250ZXh0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGdsb2JhbENvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbn1cbi8qKlxuICogTW9zdCBicm93c2VycyB3aWxsIG5vdCBwbGF5IF9hbnlfIGF1ZGlvIHVudGlsIGEgdXNlclxuICogY2xpY2tzIHNvbWV0aGluZyAobGlrZSBhIHBsYXkgYnV0dG9uKS4gSW52b2tlIHRoaXMgbWV0aG9kXG4gKiBvbiBhIGNsaWNrIG9yIGtleXByZXNzIGV2ZW50IGhhbmRsZXIgdG8gc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQuXG4gKiBNb3JlIGFib3V0IHRoZSBBdXRvcGxheSBwb2xpY3lcbiAqIFtoZXJlXShodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS93ZWIvdXBkYXRlcy8yMDE3LzA5L2F1dG9wbGF5LXBvbGljeS1jaGFuZ2VzI3dlYmF1ZGlvKVxuICogQGV4YW1wbGVcbiAqIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJidXR0b25cIikuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGFzeW5jICgpID0+IHtcbiAqIFx0YXdhaXQgVG9uZS5zdGFydCgpO1xuICogXHRjb25zb2xlLmxvZyhcImNvbnRleHQgc3RhcnRlZFwiKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIHJldHVybiBnbG9iYWxDb250ZXh0LnJlc3VtZSgpO1xufVxuLyoqXG4gKiBMb2cgVG9uZS5qcyArIHZlcnNpb24gaW4gdGhlIGNvbnNvbGUuXG4gKi9cbmlmICh0aGVXaW5kb3cgJiYgIXRoZVdpbmRvdy5UT05FX1NJTEVOQ0VfTE9HR0lORykge1xuICAgIGxldCBwcmVmaXggPSBcInZcIjtcbiAgICBpZiAodmVyc2lvbiA9PT0gXCJkZXZcIikge1xuICAgICAgICBwcmVmaXggPSBcIlwiO1xuICAgIH1cbiAgICBjb25zdCBwcmludFN0cmluZyA9IGAgKiBUb25lLmpzICR7cHJlZml4fSR7dmVyc2lvbn0gKiBgO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYCVjJHtwcmludFN0cmluZ31gLCBcImJhY2tncm91bmQ6ICMwMDA7IGNvbG9yOiAjZmZmXCIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2xvYmFsLmpzLm1hcCIsIi8qKlxuICogRXF1YWwgcG93ZXIgZ2FpbiBzY2FsZS4gR29vZCBmb3IgY3Jvc3MtZmFkaW5nLlxuICogQHBhcmFtICBwZXJjZW50ICgwLTEpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbFBvd2VyU2NhbGUocGVyY2VudCkge1xuICAgIGNvbnN0IHBpRmFjdG9yID0gMC41ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4ocGVyY2VudCAqIHBpRmFjdG9yKTtcbn1cbi8qKlxuICogQ29udmVydCBkZWNpYmVscyBpbnRvIGdhaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYlRvR2FpbihkYikge1xuICAgIHJldHVybiBNYXRoLnBvdygxMCwgZGIgLyAyMCk7XG59XG4vKipcbiAqIENvbnZlcnQgZ2FpbiB0byBkZWNpYmVscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdhaW5Ub0RiKGdhaW4pIHtcbiAgICByZXR1cm4gMjAgKiAoTWF0aC5sb2coZ2FpbikgLyBNYXRoLkxOMTApO1xufVxuLyoqXG4gKiBDb252ZXJ0IGFuIGludGVydmFsIChpbiBzZW1pdG9uZXMpIHRvIGEgZnJlcXVlbmN5IHJhdGlvLlxuICogQHBhcmFtIGludGVydmFsIHRoZSBudW1iZXIgb2Ygc2VtaXRvbmVzIGFib3ZlIHRoZSBiYXNlIG5vdGVcbiAqIEBleGFtcGxlXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygwKTsgLy8gMVxuICogVG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oMTIpOyAvLyAyXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygtMTIpOyAvLyAwLjVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCAoaW50ZXJ2YWwgLyAxMikpO1xufVxuLyoqXG4gKiBUaGUgR2xvYmFsIFtjb25jZXJ0IHR1bmluZyBwaXRjaF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uY2VydF9waXRjaCkgd2hpY2ggaXMgdXNlZFxuICogdG8gZ2VuZXJhdGUgYWxsIHRoZSBvdGhlciBwaXRjaCB2YWx1ZXMgZnJvbSBub3Rlcy4gQTQncyB2YWx1ZXMgaW4gSGVydHouXG4gKi9cbmxldCBBNCA9IDQ0MDtcbmV4cG9ydCBmdW5jdGlvbiBnZXRBNCgpIHtcbiAgICByZXR1cm4gQTQ7XG59XG5leHBvcnQgZnVuY3Rpb24gc2V0QTQoZnJlcSkge1xuICAgIEE0ID0gZnJlcTtcbn1cbi8qKlxuICogQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cbiAqIEBwYXJhbSBmcmVxdWVuY3kgVGhlIHZhbHVlIHRvIGZyZXF1ZW5jeSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQGV4YW1wbGVcbiAqIFRvbmUuZnRvbSg0NDApOyAvLyByZXR1cm5zIDY5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdG9tKGZyZXF1ZW5jeSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKGZ0b21mKGZyZXF1ZW5jeSkpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHRvIGEgZmxvYXRpbmcgcG9pbnQgbWlkaSB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZnRvbWYoZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIDY5ICsgMTIgKiBNYXRoLmxvZzIoZnJlcXVlbmN5IC8gQTQpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgTUlESSBub3RlIHRvIGZyZXF1ZW5jeSB2YWx1ZS5cbiAqIEBwYXJhbSAgbWlkaSBUaGUgbWlkaSBudW1iZXIgdG8gY29udmVydC5cbiAqIEByZXR1cm4gVGhlIGNvcnJlc3BvbmRpbmcgZnJlcXVlbmN5IHZhbHVlXG4gKiBAZXhhbXBsZVxuICogVG9uZS5tdG9mKDY5KTsgLy8gNDQwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtdG9mKG1pZGkpIHtcbiAgICByZXR1cm4gQTQgKiBNYXRoLnBvdygyLCAobWlkaSAtIDY5KSAvIDEyKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnZlcnNpb25zLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNTdHJpbmcsIGlzVW5kZWYgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVGltZUJhc2UgaXMgYSBmbGV4aWJsZSBlbmNvZGluZyBvZiB0aW1lIHdoaWNoIGNhbiBiZSBldmFsdWF0ZWQgdG8gYW5kIGZyb20gYSBzdHJpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lQmFzZUNsYXNzIGV4dGVuZHMgVG9uZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSB0aW1lIHZhbHVlLiBVc2VkIHRvIGNvbXB1dGVcbiAgICAgKiBUcmFuc3BvcnQgYW5kIGNvbnRleHQtcmVsYXRpdmUgdGltaW5nLlxuICAgICAqIEBwYXJhbSAgdmFsdWUgIFRoZSB0aW1lIHZhbHVlIGFzIGEgbnVtYmVyLCBzdHJpbmcgb3Igb2JqZWN0XG4gICAgICogQHBhcmFtICB1bml0cyAgVW5pdCB2YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCB2YWx1ZSwgdW5pdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkZWZhdWx0IHVuaXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwic1wiO1xuICAgICAgICB0aGlzLl92YWwgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5fZXhwcmVzc2lvbnMgPSB0aGlzLl9nZXRFeHByZXNzaW9ucygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbGwgb2YgdGhlIHRpbWUgZW5jb2RpbmcgZXhwcmVzc2lvbnNcbiAgICAgKi9cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoejoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3lUb1VuaXRzKHBhcnNlRmxvYXQodmFsdWUpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyloeiQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tzVG9Vbml0cyhwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKylpJC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG06IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlSW50KHZhbHVlLCAxMCkgKiB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKW0kL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlLCBkb3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NhbGFyID0gZG90ID09PSBcIi5cIiA/IDEuNSA6IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChudW1lcmljVmFsdWUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHModGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKSAqIHNjYWxhcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMoNCAvIG51bWVyaWNWYWx1ZSkgKiBzY2FsYXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyluKFxcLj8pJC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG51bWJlcjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHByZXNzaW9uc1t0aGlzLmRlZmF1bHRVbml0c10ubWV0aG9kLmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KSQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHM6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2Vjb25kc1RvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KXMkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzYW1wbGVzOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCkgLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKylzYW1wbGVzJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdDoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMoOCAvIChNYXRoLmZsb29yKG51bWVyaWNWYWx1ZSkgKiAzKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspdCQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKG0sIHEsIHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0gJiYgbSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkgKiBwYXJzZUZsb2F0KG0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocSAmJiBxICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzICYmIHMgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChzKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/JC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFZBTFVFIE9GXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogRXZhbHVhdGUgdGhlIHRpbWUgdmFsdWUuIFJldHVybnMgdGhlIHRpbWUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB2YWx1ZU9mKCkge1xuICAgICAgICBpZiAodGhpcy5fdmFsIGluc3RhbmNlb2YgVGltZUJhc2VDbGFzcykge1xuICAgICAgICAgICAgdGhpcy5mcm9tVHlwZSh0aGlzLl92YWwpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub0FyZygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRoaXMuX3ZhbCkgJiYgaXNVbmRlZih0aGlzLl91bml0cykpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdW5pdHMgaW4gdGhpcy5fZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZXhwcmVzc2lvbnNbdW5pdHNdLnJlZ2V4cC50ZXN0KHRoaXMuX3ZhbC50cmltKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VuaXRzID0gdW5pdHM7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl92YWwpKSB7XG4gICAgICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICAgICAgZm9yIChjb25zdCB0eXBlTmFtZSBpbiB0aGlzLl92YWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX3ZhbFt0eXBlTmFtZV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1YW50aXR5ID0gdGhpcy5fdmFsW3R5cGVOYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lID0gKG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgdHlwZU5hbWUpKS52YWx1ZU9mKCkgKiBxdWFudGl0eTtcbiAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGltZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdG90YWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl91bml0cykpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cHIgPSB0aGlzLl9leHByZXNzaW9uc1t0aGlzLl91bml0c107XG4gICAgICAgICAgICBjb25zdCBtYXRjaGluZyA9IHRoaXMuX3ZhbC50b1N0cmluZygpLnRyaW0oKS5tYXRjaChleHByLnJlZ2V4cCk7XG4gICAgICAgICAgICBpZiAobWF0Y2hpbmcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuYXBwbHkodGhpcywgbWF0Y2hpbmcuc2xpY2UoMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cHIubWV0aG9kLmNhbGwodGhpcywgdGhpcy5fdmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1N0cmluZyh0aGlzLl92YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh0aGlzLl92YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBmcmVxO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuICg2MCAvIHRoaXMuX2dldEJwbSgpKSAqIGJlYXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBzZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuICh0aWNrcyAqICh0aGlzLl9iZWF0c1RvVW5pdHMoMSkpIC8gdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaXRoIG5vIGFyZ3VtZW50cywgcmV0dXJuICdub3cnXG4gICAgICovXG4gICAgX25vQXJnKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbm93KCk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VEVNUE8gQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGJwbVxuICAgICAqL1xuICAgIF9nZXRCcG0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmJwbS52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lU2lnbmF0dXJlXG4gICAgICovXG4gICAgX2dldFRpbWVTaWduYXR1cmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpbWVTaWduYXR1cmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgUFBRIG9yIDE5MiBpZiBUcmFuc3BvcnQgaXMgbm90IGF2YWlsYWJsZVxuICAgICAqL1xuICAgIF9nZXRQUFEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LlBQUTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRDT05WRVJTSU9OIElOVEVSRkFDRVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIENvZXJjZSBhIHRpbWUgdHlwZSBpbnRvIHRoaXMgdW5pdHMgdHlwZS5cbiAgICAgKiBAcGFyYW0gdHlwZSBBbnkgdGltZSB0eXBlIHVuaXRzXG4gICAgICovXG4gICAgZnJvbVR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl91bml0cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgc3dpdGNoICh0aGlzLmRlZmF1bHRVbml0cykge1xuICAgICAgICAgICAgY2FzZSBcInNcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImlcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvVGlja3MoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJoelwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9GcmVxdWVuY3koKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJtaWRpXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b01pZGkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBpbiBoZXJ0elxuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gMSAvIHRoaXMudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBzYW1wbGVzXG4gICAgICovXG4gICAgdG9TYW1wbGVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHMoKSAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzLlxuICAgICAqL1xuICAgIHRvTWlsbGlzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHMoKSAqIDEwMDA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZUJhc2UuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGZ0b20gfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgVGltZUJhc2VDbGFzcyB9IGZyb20gXCIuL1RpbWVCYXNlXCI7XG4vKipcbiAqIFRpbWVDbGFzcyBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBUaW1lQ2xhc3MgY2FuIGJlIHBhc3NlZCBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQHBhcmFtICB2YWwgICAgVGhlIHRpbWUgdmFsdWUuXG4gKiBAcGFyYW0gIHVuaXRzICBUaGUgdW5pdHMgb2YgdGhlIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHRpbWUgPSBUb25lLlRpbWUoXCI0blwiKTsgLy8gYSBxdWFydGVyIG5vdGVcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lQ2xhc3MgZXh0ZW5kcyBUaW1lQmFzZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lQ2xhc3NcIjtcbiAgICB9XG4gICAgX2dldEV4cHJlc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihzdXBlci5fZ2V0RXhwcmVzc2lvbnMoKSwge1xuICAgICAgICAgICAgbm93OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAoY2FwdHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm93KCkgKyBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmNvbnRleHQsIGNhcHR1cmUpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL15cXCsoLispLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWFudGl6ZToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKGNhcHR1cmUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRUbyA9IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBjYXB0dXJlKS52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyh0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm5leHRTdWJkaXZpc2lvbihxdWFudFRvKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eQCguKykvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFF1YW50aXplIHRoZSB0aW1lIGJ5IHRoZSBnaXZlbiBzdWJkaXZpc2lvbi4gT3B0aW9uYWxseSBhZGQgYVxuICAgICAqIHBlcmNlbnRhZ2Ugd2hpY2ggd2lsbCBtb3ZlIHRoZSB0aW1lIHZhbHVlIHRvd2FyZHMgdGhlIGlkZWFsXG4gICAgICogcXVhbnRpemVkIHZhbHVlIGJ5IHRoYXQgcGVyY2VudGFnZS5cbiAgICAgKiBAcGFyYW0gIHN1YmRpdiAgICBUaGUgc3ViZGl2aXNpb24gdG8gcXVhbnRpemUgdG9cbiAgICAgKiBAcGFyYW0gIHBlcmNlbnQgIE1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgcXVhbnRpemVkIHZhbHVlIGJ5IGEgcGVyY2VudGFnZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVGltZSgyMSkucXVhbnRpemUoMik7IC8vIHJldHVybnMgMjJcbiAgICAgKiBUb25lLlRpbWUoMC42KS5xdWFudGl6ZShcIjRuXCIsIDAuNSk7IC8vIHJldHVybnMgMC41NVxuICAgICAqL1xuICAgIHF1YW50aXplKHN1YmRpdiwgcGVyY2VudCA9IDEpIHtcbiAgICAgICAgY29uc3Qgc3ViZGl2aXNpb24gPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmNvbnRleHQsIHN1YmRpdikudmFsdWVPZigpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmFsdWVPZigpO1xuICAgICAgICBjb25zdCBtdWx0aXBsZSA9IE1hdGgucm91bmQodmFsdWUgLyBzdWJkaXZpc2lvbik7XG4gICAgICAgIGNvbnN0IGlkZWFsID0gbXVsdGlwbGUgKiBzdWJkaXZpc2lvbjtcbiAgICAgICAgY29uc3QgZGlmZiA9IGlkZWFsIC0gdmFsdWU7XG4gICAgICAgIHJldHVybiB2YWx1ZSArIGRpZmYgKiBwZXJjZW50O1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBUaW1lIHRvIE5vdGF0aW9uLiBUaGUgbm90YXRpb24gdmFsdWVzIGFyZSB3aWxsIGJlIHRoZVxuICAgICAqIGNsb3Nlc3QgcmVwcmVzZW50YXRpb24gYmV0d2VlbiAxbSB0byAxMjh0aCBub3RlLlxuICAgICAqIEByZXR1cm4ge05vdGF0aW9ufVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gaWYgdGhlIFRyYW5zcG9ydCBpcyBhdCAxMjBicG06XG4gICAgICogVG9uZS5UaW1lKDIpLnRvTm90YXRpb24oKTsgLy8gcmV0dXJucyBcIjFtXCJcbiAgICAgKi9cbiAgICB0b05vdGF0aW9uKCkge1xuICAgICAgICBjb25zdCB0aW1lID0gdGhpcy50b1NlY29uZHMoKTtcbiAgICAgICAgY29uc3QgdGVzdE5vdGF0aW9ucyA9IFtcIjFtXCJdO1xuICAgICAgICBmb3IgKGxldCBwb3dlciA9IDE7IHBvd2VyIDwgOTsgcG93ZXIrKykge1xuICAgICAgICAgICAgY29uc3Qgc3ViZGl2ID0gTWF0aC5wb3coMiwgcG93ZXIpO1xuICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArIFwibi5cIik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJuXCIpO1xuICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArIFwidFwiKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goXCIwXCIpO1xuICAgICAgICAvLyBmaW5kIHRoZSBjbG9zZXRzIG5vdGF0aW9uIHJlcHJlc2VudGF0aW9uXG4gICAgICAgIGxldCBjbG9zZXN0ID0gdGVzdE5vdGF0aW9uc1swXTtcbiAgICAgICAgbGV0IGNsb3Nlc3RTZWNvbmRzID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRlc3ROb3RhdGlvbnNbMF0pLnRvU2Vjb25kcygpO1xuICAgICAgICB0ZXN0Tm90YXRpb25zLmZvckVhY2gobm90YXRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm90YXRpb25TZWNvbmRzID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGF0aW9uKS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhub3RhdGlvblNlY29uZHMgLSB0aW1lKSA8IE1hdGguYWJzKGNsb3Nlc3RTZWNvbmRzIC0gdGltZSkpIHtcbiAgICAgICAgICAgICAgICBjbG9zZXN0ID0gbm90YXRpb247XG4gICAgICAgICAgICAgICAgY2xvc2VzdFNlY29uZHMgPSBub3RhdGlvblNlY29uZHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2xvc2VzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGVuY29kZWQgYXMgQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuICAgICAqL1xuICAgIHRvQmFyc0JlYXRzU2l4dGVlbnRocygpIHtcbiAgICAgICAgY29uc3QgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG4gICAgICAgIGxldCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHF1YXJ0ZXJzID0gcGFyc2VGbG9hdChxdWFydGVycy50b0ZpeGVkKDQpKTtcbiAgICAgICAgY29uc3QgbWVhc3VyZXMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzIC8gdGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKTtcbiAgICAgICAgbGV0IHNpeHRlZW50aHMgPSAocXVhcnRlcnMgJSAxKSAqIDQ7XG4gICAgICAgIHF1YXJ0ZXJzID0gTWF0aC5mbG9vcihxdWFydGVycykgJSB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCk7XG4gICAgICAgIGNvbnN0IHNpeHRlZW50aFN0cmluZyA9IHNpeHRlZW50aHMudG9TdHJpbmcoKTtcbiAgICAgICAgaWYgKHNpeHRlZW50aFN0cmluZy5sZW5ndGggPiAzKSB7XG4gICAgICAgICAgICAvLyB0aGUgYWRkaXRpb25hbCBwYXJzZUZsb2F0IHJlbW92ZXMgaW5zaWduaWZpY2FudCB0cmFpbGluZyB6ZXJvZXNcbiAgICAgICAgICAgIHNpeHRlZW50aHMgPSBwYXJzZUZsb2F0KHBhcnNlRmxvYXQoc2l4dGVlbnRoU3RyaW5nKS50b0ZpeGVkKDMpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9ncmVzcyA9IFttZWFzdXJlcywgcXVhcnRlcnMsIHNpeHRlZW50aHNdO1xuICAgICAgICByZXR1cm4gcHJvZ3Jlc3Muam9pbihcIjpcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiB0aWNrcy5cbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgY29uc3QgcXVhcnRlcnMgPSB0aGlzLnZhbHVlT2YoKSAvIHF1YXJ0ZXJUaW1lO1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChxdWFydGVycyAqIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgYXMgYSBtaWRpIG5vdGUuXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gZnRvbSh0aGlzLnRvRnJlcXVlbmN5KCkpO1xuICAgIH1cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0Lm5vdygpO1xuICAgIH1cbn1cbi8qKlxuICogQ3JlYXRlIGEgVGltZUNsYXNzIGZyb20gYSB0aW1lIHN0cmluZyBvciBudW1iZXIuIFRoZSB0aW1lIGlzIGNvbXB1dGVkIGFnYWluc3QgdGhlXG4gKiBnbG9iYWwgVG9uZS5Db250ZXh0LiBUbyB1c2UgYSBzcGVjaWZpYyBjb250ZXh0LCB1c2UgW1tUaW1lQ2xhc3NdXVxuICogQHBhcmFtIHZhbHVlIEEgdmFsdWUgd2hpY2ggcmVwcmVzZW50cyB0aW1lXG4gKiBAcGFyYW0gdW5pdHMgVGhlIHZhbHVlJ3MgdW5pdHMgaWYgdGhleSBjYW4ndCBiZSBpbmZlcnJlZCBieSB0aGUgdmFsdWUuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHRpbWUgPSBUb25lLlRpbWUoXCI0blwiKS50b1NlY29uZHMoKTtcbiAqIGNvbnNvbGUubG9nKHRpbWUpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5vdGUgPSBUb25lLlRpbWUoMSkudG9Ob3RhdGlvbigpO1xuICogY29uc29sZS5sb2cobm90ZSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgZnJlcSA9IFRvbmUuVGltZSgwLjUpLnRvRnJlcXVlbmN5KCk7XG4gKiBjb25zb2xlLmxvZyhmcmVxKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRpbWUodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvLCBtdG9mIH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGZ0b20sIGdldEE0LCBzZXRBNCB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi9UaW1lXCI7XG4vKipcbiAqIEZyZXF1ZW5jeSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBGcmVxdWVuY3kgdmFsdWVzLlxuICogRXZlbnR1YWxseSBhbGwgdGltZSB2YWx1ZXMgYXJlIGV2YWx1YXRlZCB0byBoZXJ0eiB1c2luZyB0aGUgYHZhbHVlT2ZgIG1ldGhvZC5cbiAqIEBleGFtcGxlXG4gKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpOyAvLyAyNjFcbiAqIFRvbmUuRnJlcXVlbmN5KDM4LCBcIm1pZGlcIik7XG4gKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRyYW5zcG9zZSg0KTtcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lDbGFzcyBleHRlbmRzIFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlcXVlbmN5XCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJoelwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgW2NvbmNlcnQgdHVuaW5nIHBpdGNoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXJ0X3BpdGNoKSB3aGljaCBpcyB1c2VkXG4gICAgICogdG8gZ2VuZXJhdGUgYWxsIHRoZSBvdGhlciBwaXRjaCB2YWx1ZXMgZnJvbSBub3Rlcy4gQTQncyB2YWx1ZXMgaW4gSGVydHouXG4gICAgICovXG4gICAgc3RhdGljIGdldCBBNCgpIHtcbiAgICAgICAgcmV0dXJuIGdldEE0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBzZXQgQTQoZnJlcSkge1xuICAgICAgICBzZXRBNChmcmVxKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRBVUdNRU5UIEJBU0UgRVhQUkVTU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fZ2V0RXhwcmVzc2lvbnMoKSwge1xuICAgICAgICAgICAgbWlkaToge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspP21pZGkpLyxcbiAgICAgICAgICAgICAgICBtZXRob2QodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFVuaXRzID09PSBcIm1pZGlcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZyZXF1ZW5jeUNsYXNzLm10b2YodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBub3RlOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihbYS1nXXsxfSg/OmJ8I3x4fGJiKT8pKC0/WzAtOV0rKS9pLFxuICAgICAgICAgICAgICAgIG1ldGhvZChwaXRjaCwgb2N0YXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbm90ZVRvU2NhbGVJbmRleFtwaXRjaC50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm90ZU51bWJlciA9IGluZGV4ICsgKHBhcnNlSW50KG9jdGF2ZSwgMTApICsgMSkgKiAxMjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFVuaXRzID09PSBcIm1pZGlcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vdGVOdW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnJlcXVlbmN5Q2xhc3MubXRvZihub3RlTnVtYmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHI6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pOihcXGQrKD86XFwuXFxkKyk/KTo/KFxcZCsoPzpcXC5cXGQrKT8pPy8sXG4gICAgICAgICAgICAgICAgbWV0aG9kKG0sIHEsIHMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0gJiYgbSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkgKiBwYXJzZUZsb2F0KG0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocSAmJiBxICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzICYmIHMgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChzKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0RVhQUkVTU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBUcmFuc3Bvc2VzIHRoZSBmcmVxdWVuY3kgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBzZW1pdG9uZXMuXG4gICAgICogQHJldHVybiAgQSBuZXcgdHJhbnNwb3NlZCBmcmVxdWVuY3lcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KFwiQTRcIikudHJhbnNwb3NlKDMpOyAvLyBcIkM1XCJcbiAgICAgKi9cbiAgICB0cmFuc3Bvc2UoaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMudmFsdWVPZigpICogaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRha2VzIGFuIGFycmF5IG9mIHNlbWl0b25lIGludGVydmFscyBhbmQgcmV0dXJuc1xuICAgICAqIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzIHRyYW5zcG9zZWQgYnkgdGhvc2UgaW50ZXJ2YWxzLlxuICAgICAqIEByZXR1cm4gIFJldHVybnMgYW4gYXJyYXkgb2YgRnJlcXVlbmNpZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KFwiQTRcIikuaGFybW9uaXplKFswLCAzLCA3XSk7IC8vIFtcIkE0XCIsIFwiQzVcIiwgXCJFNVwiXVxuICAgICAqL1xuICAgIGhhcm1vbml6ZShpbnRlcnZhbHMpIHtcbiAgICAgICAgcmV0dXJuIGludGVydmFscy5tYXAoaW50ZXJ2YWwgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNwb3NlKGludGVydmFsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJDNFwiKS50b01pZGkoKTsgLy8gNjBcbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHRoaXMudmFsdWVPZigpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGluIFNjaWVudGlmaWMgUGl0Y2ggTm90YXRpb25cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KDY5LCBcIm1pZGlcIikudG9Ob3RlKCk7IC8vIFwiQTRcIlxuICAgICAqL1xuICAgIHRvTm90ZSgpIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3koKTtcbiAgICAgICAgY29uc3QgbG9nID0gTWF0aC5sb2cyKGZyZXEgLyBGcmVxdWVuY3lDbGFzcy5BNCk7XG4gICAgICAgIGxldCBub3RlTnVtYmVyID0gTWF0aC5yb3VuZCgxMiAqIGxvZykgKyA1NztcbiAgICAgICAgY29uc3Qgb2N0YXZlID0gTWF0aC5mbG9vcihub3RlTnVtYmVyIC8gMTIpO1xuICAgICAgICBpZiAob2N0YXZlIDwgMCkge1xuICAgICAgICAgICAgbm90ZU51bWJlciArPSAtMTIgKiBvY3RhdmU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgbm90ZU5hbWUgPSBzY2FsZUluZGV4VG9Ob3RlW25vdGVOdW1iZXIgJSAxMl07XG4gICAgICAgIHJldHVybiBub3RlTmFtZSArIG9jdGF2ZS50b1N0cmluZygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHRvU2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBzdXBlci50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBkdXJhdGlvbiBvZiBvbmUgY3ljbGUgaW4gdGlja3NcbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgY29uc3QgcXVhcnRlcnMgPSB0aGlzLnZhbHVlT2YoKSAvIHF1YXJ0ZXJUaW1lO1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihxdWFydGVycyAqIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TIEhFTFBFUlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBXaXRoIG5vIGFyZ3VtZW50cywgcmV0dXJuIDBcbiAgICAgKi9cbiAgICBfbm9BcmcoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIGZyZXE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gMSAvICgodGlja3MgKiA2MCkgLyAodGhpcy5fZ2V0QnBtKCkgKiB0aGlzLl9nZXRQUFEoKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBzdXBlci5fYmVhdHNUb1VuaXRzKGJlYXRzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gMSAvIHNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqIEBwYXJhbSAgbWlkaSBUaGUgbWlkaSBudW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJuIFRoZSBjb3JyZXNwb25kaW5nIGZyZXF1ZW5jeSB2YWx1ZVxuICAgICAqL1xuICAgIHN0YXRpYyBtdG9mKG1pZGkpIHtcbiAgICAgICAgcmV0dXJuIG10b2YobWlkaSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdmFsdWUgdG8gYSBNSURJIG5vdGUuXG4gICAgICogQHBhcmFtIGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICovXG4gICAgc3RhdGljIGZ0b20oZnJlcXVlbmN5KSB7XG4gICAgICAgIHJldHVybiBmdG9tKGZyZXF1ZW5jeSk7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdEZSRVFVRU5DWSBDT05WRVJTSU9OU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIE5vdGUgdG8gc2NhbGUgaW5kZXguXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IG5vdGVUb1NjYWxlSW5kZXggPSB7XG4gICAgY2JiOiAtMiwgY2I6IC0xLCBjOiAwLCBcImMjXCI6IDEsIGN4OiAyLFxuICAgIGRiYjogMCwgZGI6IDEsIGQ6IDIsIFwiZCNcIjogMywgZHg6IDQsXG4gICAgZWJiOiAyLCBlYjogMywgZTogNCwgXCJlI1wiOiA1LCBleDogNixcbiAgICBmYmI6IDMsIGZiOiA0LCBmOiA1LCBcImYjXCI6IDYsIGZ4OiA3LFxuICAgIGdiYjogNSwgZ2I6IDYsIGc6IDcsIFwiZyNcIjogOCwgZ3g6IDksXG4gICAgYWJiOiA3LCBhYjogOCwgYTogOSwgXCJhI1wiOiAxMCwgYXg6IDExLFxuICAgIGJiYjogOSwgYmI6IDEwLCBiOiAxMSwgXCJiI1wiOiAxMiwgYng6IDEzLFxufTtcbi8qKlxuICogc2NhbGUgaW5kZXggdG8gbm90ZSAoc2hhcnBzKVxuICogQGhpZGRlblxuICovXG5jb25zdCBzY2FsZUluZGV4VG9Ob3RlID0gW1wiQ1wiLCBcIkMjXCIsIFwiRFwiLCBcIkQjXCIsIFwiRVwiLCBcIkZcIiwgXCJGI1wiLCBcIkdcIiwgXCJHI1wiLCBcIkFcIiwgXCJBI1wiLCBcIkJcIl07XG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIGEgRnJlcXVlbmN5Q2xhc3Mgb2JqZWN0LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtaWRpID0gVG9uZS5GcmVxdWVuY3koXCJDM1wiKS50b01pZGkoKTtcbiAqIGNvbnNvbGUubG9nKG1pZGkpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IGhlcnR6ID0gVG9uZS5GcmVxdWVuY3koMzgsIFwibWlkaVwiKS50b0ZyZXF1ZW5jeSgpO1xuICogY29uc29sZS5sb2coaGVydHopO1xuICovXG5leHBvcnQgZnVuY3Rpb24gRnJlcXVlbmN5KHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlcXVlbmN5LmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi9UaW1lXCI7XG4vKipcbiAqIFRyYW5zcG9ydFRpbWUgaXMgYSB0aGUgdGltZSBhbG9uZyB0aGUgVHJhbnNwb3J0J3NcbiAqIHRpbWVsaW5lLiBJdCBpcyBzaW1pbGFyIHRvIFRvbmUuVGltZSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuICogYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG4gKiB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRUaW1lQ2xhc3MgZXh0ZW5kcyBUaW1lQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyYW5zcG9ydFRpbWVcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgaW4gd2hpY2hldmVyIGNvbnRleHQgaXMgcmVsZXZhbnRcbiAgICAgKi9cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzO1xuICAgIH1cbn1cbi8qKlxuICogVHJhbnNwb3J0VGltZSBpcyBhIHRoZSB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuICogdGltZWxpbmUuIEl0IGlzIHNpbWlsYXIgdG8gW1tUaW1lXV0sIGJ1dCBpbnN0ZWFkIG9mIGV2YWx1YXRpbmdcbiAqIGFnYWluc3QgdGhlIEF1ZGlvQ29udGV4dCdzIGNsb2NrLCBpdCBpcyBldmFsdWF0ZWQgYWdhaW5zdFxuICogdGhlIFRyYW5zcG9ydCdzIHBvc2l0aW9uLiBTZWUgW1RyYW5zcG9ydFRpbWUgd2lraV0oaHR0cHM6Ly9naXRodWIuY29tL1RvbmVqcy9Ub25lLmpzL3dpa2kvVHJhbnNwb3J0VGltZSkuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgZnVuY3Rpb24gVHJhbnNwb3J0VGltZSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmFuc3BvcnRUaW1lLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaW1lXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZSwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNCb29sZWFuLCBpc0RlZmluZWQsIGlzTnVtYmVyLCBpc1N0cmluZywgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUaGUgQmFzZSBjbGFzcyBmb3IgYWxsIG5vZGVzIHRoYXQgaGF2ZSBhbiBBdWRpb0NvbnRleHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lV2l0aENvbnRleHQgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNvbnRleHRcIl0pO1xuICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29udGV4dCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gdGhpcy5kZWZhdWx0Q29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRDb250ZXh0KCksXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSBDb250ZXh0IGNsb2NrIHBsdXMgdGhlIGxvb2tBaGVhZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgKiBcdGNvbnNvbGUubG9nKFRvbmUubm93KCkpO1xuICAgICAqIH0sIDEwMCk7XG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICsgdGhpcy5jb250ZXh0Lmxvb2tBaGVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIENvbnRleHQgY2xvY2sgd2l0aG91dCBhbnkgbG9va0FoZWFkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2coVG9uZS5pbW1lZGlhdGUoKSk7XG4gICAgICogfSwgMTAwKTtcbiAgICAgKi9cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIG9mIG9uZSBzYW1wbGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLlRyYW5zcG9ydC5zYW1wbGVUaW1lKTtcbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlVGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDEgLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBzZWNvbmRzIG9mIDEgcHJvY2Vzc2luZyBibG9jayAoMTI4IHNhbXBsZXMpXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLkRlc3RpbmF0aW9uLmJsb2NrVGltZSk7XG4gICAgICovXG4gICAgZ2V0IGJsb2NrVGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDEyOCAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbmNvbWluZyB0aW1lIHRvIHNlY29uZHMuXG4gICAgICogVGhpcyBpcyBjYWxjdWxhdGVkIGFnYWluc3QgdGhlIGN1cnJlbnQgW1tUb25lLlRyYW5zcG9ydF1dIGJwbVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZ2FpbiA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhnYWluLnRvU2Vjb25kcyhcIjRuXCIpKSwgMTAwKTtcbiAgICAgKiAvLyByYW1wIHRoZSB0ZW1wbyB0byA2MCBicG0gb3ZlciAzMCBzZWNvbmRzXG4gICAgICogVG9uZS5nZXRUcmFuc3BvcnQoKS5icG0ucmFtcFRvKDYwLCAzMCk7XG4gICAgICovXG4gICAgdG9TZWNvbmRzKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgaW5wdXQgdG8gYSBmcmVxdWVuY3kgbnVtYmVyXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKGdhaW4udG9GcmVxdWVuY3koXCI0blwiKSk7XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koZnJlcSkge1xuICAgICAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgZnJlcSkudG9GcmVxdWVuY3koKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgaW5wdXQgdGltZSBpbnRvIHRpY2tzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKGdhaW4udG9UaWNrcyhcIjRuXCIpKTtcbiAgICAgKi9cbiAgICB0b1RpY2tzKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1RpY2tzKCk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0R0VUL1NFVFxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEdldCBhIHN1YnNldCBvZiB0aGUgcHJvcGVydGllcyB3aGljaCBhcmUgaW4gdGhlIHBhcnRpYWwgcHJvcHNcbiAgICAgKi9cbiAgICBfZ2V0UGFydGlhbFByb3BlcnRpZXMocHJvcHMpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0KCk7XG4gICAgICAgIC8vIHJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gdGhlIHByb3AgdGhhdCBhcmUgbm90IGluIHRoZSBwYXJ0aWFsXG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZihwcm9wc1tuYW1lXSkpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgb3B0aW9uc1tuYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG9iamVjdCdzIGF0dHJpYnV0ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogY29uc29sZS5sb2cob3NjLmdldCgpKTtcbiAgICAgKi9cbiAgICBnZXQoKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gZ2V0RGVmYXVsdHNGcm9tSW5zdGFuY2UodGhpcyk7XG4gICAgICAgIE9iamVjdC5rZXlzKGRlZmF1bHRzKS5mb3JFYWNoKGF0dHJpYnV0ZSA9PiB7XG4gICAgICAgICAgICBpZiAoUmVmbGVjdC5oYXModGhpcywgYXR0cmlidXRlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlciA9IHRoaXNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKG1lbWJlcikgJiYgaXNEZWZpbmVkKG1lbWJlci52YWx1ZSkgJiYgaXNEZWZpbmVkKG1lbWJlci5zZXRWYWx1ZUF0VGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlci52YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAobWVtYmVyIGluc3RhbmNlb2YgVG9uZVdpdGhDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzW2F0dHJpYnV0ZV0gPSBtZW1iZXIuX2dldFBhcnRpYWxQcm9wZXJ0aWVzKGRlZmF1bHRzW2F0dHJpYnV0ZV0pO1xuICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgbWFrZSBzdXJlIGl0J3MgYSBzZXJpYWxpemFibGUgdHlwZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc0FycmF5KG1lbWJlcikgfHwgaXNOdW1iZXIobWVtYmVyKSB8fCBpc1N0cmluZyhtZW1iZXIpIHx8IGlzQm9vbGVhbihtZW1iZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzW2F0dHJpYnV0ZV0gPSBtZW1iZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgYWxsIHVuZGVmaW5lZCBhbmQgdW5zZXJpYWxpemFibGUgYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgZGVmYXVsdHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBtdWx0aXBsZSBwcm9wZXJ0aWVzIGF0IG9uY2Ugd2l0aCBhbiBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc2V0IHZhbHVlcyB1c2luZyBhbiBvYmplY3RcbiAgICAgKiBmaWx0ZXIuc2V0KHtcbiAgICAgKiBcdGZyZXF1ZW5jeTogXCJDNlwiLFxuICAgICAqIFx0dHlwZTogXCJoaWdocGFzc1wiXG4gICAgICogfSk7XG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvQW5hbG9nc3ludGhfb2N0YXZlc19oaWdobWlkLm1wM1wiKS5jb25uZWN0KGZpbHRlcik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0KHByb3BzKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHByb3BzKS5mb3JFYWNoKGF0dHJpYnV0ZSA9PiB7XG4gICAgICAgICAgICBpZiAoUmVmbGVjdC5oYXModGhpcywgYXR0cmlidXRlKSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2F0dHJpYnV0ZV0gJiYgaXNEZWZpbmVkKHRoaXNbYXR0cmlidXRlXS52YWx1ZSkgJiYgaXNEZWZpbmVkKHRoaXNbYXR0cmlidXRlXS5zZXRWYWx1ZUF0VGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc21hbGwgb3B0aW1pemF0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2F0dHJpYnV0ZV0udmFsdWUgIT09IHByb3BzW2F0dHJpYnV0ZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXS52YWx1ZSA9IHByb3BzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpc1thdHRyaWJ1dGVdIGluc3RhbmNlb2YgVG9uZVdpdGhDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXS5zZXQocHJvcHNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW2F0dHJpYnV0ZV0gPSBwcm9wc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVXaXRoQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuL0RlYnVnXCI7XG4vKipcbiAqIEEgVGltZWxpbmUgU3RhdGUuIFByb3ZpZGVzIHRoZSBtZXRob2RzOiBgc2V0U3RhdGVBdFRpbWUoXCJzdGF0ZVwiLCB0aW1lKWAgYW5kIGBnZXRWYWx1ZUF0VGltZSh0aW1lKWBcbiAqIEBwYXJhbSBpbml0aWFsIFRoZSBpbml0aWFsIHN0YXRlIG9mIHRoZSBTdGF0ZVRpbWVsaW5lLiAgRGVmYXVsdHMgdG8gYHVuZGVmaW5lZGBcbiAqL1xuZXhwb3J0IGNsYXNzIFN0YXRlVGltZWxpbmUgZXh0ZW5kcyBUaW1lbGluZSB7XG4gICAgY29uc3RydWN0b3IoaW5pdGlhbCA9IFwic3RvcHBlZFwiKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3RhdGVUaW1lbGluZVwiO1xuICAgICAgICB0aGlzLl9pbml0aWFsID0gaW5pdGlhbDtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZUF0VGltZSh0aGlzLl9pbml0aWFsLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIHNjaGVkdWxlZCBiZWZvcmUgb3IgYXRcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm4gIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSBpbnB1dCBpbiBzZXRTdGF0ZUF0VGltZS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5nZXQodGltZSk7XG4gICAgICAgIGlmIChldmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRpYWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgc3RhdGUgdG8gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEFueSBhZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBhcmUgbmVlZGVkIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBzZXRTdGF0ZUF0VGltZShzdGF0ZSwgdGltZSwgb3B0aW9ucykge1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwKTtcbiAgICAgICAgdGhpcy5hZGQoT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywge1xuICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgICB0aW1lLFxuICAgICAgICB9KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGV2ZW50IGJlZm9yZSB0aGUgdGltZSB3aXRoIHRoZSBnaXZlbiBzdGF0ZVxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIHN0YXRlIHRvIGxvb2sgZm9yXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGNoZWNrIGJlZm9yZVxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aXRoIHRoZSBnaXZlbiBzdGF0ZSBiZWZvcmUgdGhlIHRpbWVcbiAgICAgKi9cbiAgICBnZXRMYXN0U3RhdGUoc3RhdGUsIHRpbWUpIHtcbiAgICAgICAgLy8gdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZVtpXTtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBldmVudCBhZnRlciB0aGUgdGltZSB3aXRoIHRoZSBnaXZlbiBzdGF0ZVxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIHN0YXRlIHRvIGxvb2sgZm9yXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGNoZWNrIGZyb21cbiAgICAgKiBAcmV0dXJuICBUaGUgZXZlbnQgd2l0aCB0aGUgZ2l2ZW4gc3RhdGUgYWZ0ZXIgdGhlIHRpbWVcbiAgICAgKi9cbiAgICBnZXROZXh0U3RhdGUoc3RhdGUsIHRpbWUpIHtcbiAgICAgICAgLy8gdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0YXRlVGltZWxpbmUuanMubWFwIiwiaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuL1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vdXRpbC9NYXRoXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogUGFyYW0gd3JhcHMgdGhlIG5hdGl2ZSBXZWIgQXVkaW8ncyBBdWRpb1BhcmFtIHRvIHByb3ZpZGVcbiAqIGFkZGl0aW9uYWwgdW5pdCBjb252ZXJzaW9uIGZ1bmN0aW9uYWxpdHkuIEl0IGFsc29cbiAqIHNlcnZlcyBhcyBhIGJhc2UtY2xhc3MgZm9yIGNsYXNzZXMgd2hpY2ggaGF2ZSBhIHNpbmdsZSxcbiAqIGF1dG9tYXRhYmxlIHBhcmFtZXRlci5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXJhbSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFyYW1cIiwgXCJ1bml0c1wiLCBcImNvbnZlcnRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXJhbVwiO1xuICAgICAgICB0aGlzLm92ZXJyaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbWluT3V0cHV0ID0gMWUtNztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFyYW1cIiwgXCJ1bml0c1wiLCBcImNvbnZlcnRcIl0pO1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKG9wdGlvbnMucGFyYW0pICYmXG4gICAgICAgICAgICAoaXNBdWRpb1BhcmFtKG9wdGlvbnMucGFyYW0pIHx8IG9wdGlvbnMucGFyYW0gaW5zdGFuY2VvZiBQYXJhbSksIFwicGFyYW0gbXVzdCBiZSBhbiBBdWRpb1BhcmFtXCIpO1xuICAgICAgICB3aGlsZSAoIWlzQXVkaW9QYXJhbShvcHRpb25zLnBhcmFtKSkge1xuICAgICAgICAgICAgb3B0aW9ucy5wYXJhbSA9IG9wdGlvbnMucGFyYW0uX3BhcmFtO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N3YXBwYWJsZSA9IGlzRGVmaW5lZChvcHRpb25zLnN3YXBwYWJsZSkgPyBvcHRpb25zLnN3YXBwYWJsZSA6IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fc3dhcHBhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgIC8vIGluaXRpYWxpemVcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtID0gb3B0aW9ucy5wYXJhbTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbSA9IHRoaXMuaW5wdXQgPSBvcHRpb25zLnBhcmFtO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZSgxMDAwKTtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlID0gdGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlO1xuICAgICAgICB0aGlzLnVuaXRzID0gb3B0aW9ucy51bml0cztcbiAgICAgICAgdGhpcy5jb252ZXJ0ID0gb3B0aW9ucy5jb252ZXJ0O1xuICAgICAgICB0aGlzLl9taW5WYWx1ZSA9IG9wdGlvbnMubWluVmFsdWU7XG4gICAgICAgIHRoaXMuX21heFZhbHVlID0gb3B0aW9ucy5tYXhWYWx1ZTtcbiAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIGRlZmluZWQsIHNldCBpdCBpbW1lZGlhdGVseVxuICAgICAgICBpZiAoaXNEZWZpbmVkKG9wdGlvbnMudmFsdWUpICYmIG9wdGlvbnMudmFsdWUgIT09IHRoaXMuX3RvVHlwZSh0aGlzLl9pbml0aWFsVmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUobm93KTtcbiAgICB9XG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMubm93KCkpO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICAvLyBpZiBpdCdzIG5vdCB0aGUgZGVmYXVsdCBtaW5WYWx1ZSwgcmV0dXJuIGl0XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fbWluVmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWluVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJ0aW1lXCIgfHwgdGhpcy51bml0cyA9PT0gXCJmcmVxdWVuY3lcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJub3JtYWxSYW5nZVwiIHx8IHRoaXMudW5pdHMgPT09IFwicG9zaXRpdmVcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJ0cmFuc3BvcnRUaW1lXCIgfHwgdGhpcy51bml0cyA9PT0gXCJ0aWNrc1wiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcImJwbVwiIHx8IHRoaXMudW5pdHMgPT09IFwiaGVydHpcIiB8fCB0aGlzLnVuaXRzID09PSBcInNhbXBsZXNcIikge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJhdWRpb1JhbmdlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAtSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWluVmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX21heFZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21heFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwibm9ybWFsUmFuZ2VcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJhdWRpb1JhbmdlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1heFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUgZ3VhcmQgYmFzZWQgb24gdGhlIHVuaXQgbmFtZVxuICAgICAqL1xuICAgIF9pcyhhcmcsIHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5pdHMgPT09IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1ha2Ugc3VyZSB0aGUgdmFsdWUgaXMgYWx3YXlzIGluIHRoZSBkZWZpbmVkIHJhbmdlXG4gICAgICovXG4gICAgX2Fzc2VydFJhbmdlKHZhbHVlKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5tYXhWYWx1ZSkgJiYgaXNEZWZpbmVkKHRoaXMubWluVmFsdWUpKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh2YWx1ZSwgdGhpcy5fZnJvbVR5cGUodGhpcy5taW5WYWx1ZSksIHRoaXMuX2Zyb21UeXBlKHRoaXMubWF4VmFsdWUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGdpdmVuIHZhbHVlIGZyb20gdGhlIHR5cGUgc3BlY2lmaWVkIGJ5IFBhcmFtLnVuaXRzXG4gICAgICogaW50byB0aGUgZGVzdGluYXRpb24gdmFsdWUgKHN1Y2ggYXMgR2FpbiBvciBGcmVxdWVuY3kpLlxuICAgICAqL1xuICAgIF9mcm9tVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udmVydCAmJiAhdGhpcy5vdmVycmlkZGVuKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXModmFsLCBcInRpbWVcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHModmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2lzKHZhbCwgXCJkZWNpYmVsc1wiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYlRvR2Fpbih2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXModmFsLCBcImZyZXF1ZW5jeVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvRnJlcXVlbmN5KHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3ZlcnJpZGRlbikge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBvdmVycmlkZGVuLCBzaG91bGQgb25seSBzY2hlZHVsZSAwc1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIHBhcmFtZXRlcnMgdmFsdWUgaW50byB0aGUgdW5pdHMgc3BlY2lmaWVkIGJ5IFBhcmFtLnVuaXRzLlxuICAgICAqL1xuICAgIF90b1R5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnZlcnQgJiYgdGhpcy51bml0cyA9PT0gXCJkZWNpYmVsc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2FpblRvRGIodmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQUJTVFJBQ1QgUEFSQU0gSU5URVJGQUNFXG4gICAgLy8gYWxsIGRvY3MgYXJlIGdlbmVyYXRlZCBmcm9tIFBhcmFtSW50ZXJmYWNlLnRzXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gc2V0VmFsdWVBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJzZXRWYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBNYXRoLm1heCh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgMCk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgbGV0IHZhbHVlID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICAvLyBpZiBpdCB3YXMgc2V0IGJ5XG4gICAgICAgIGlmIChiZWZvcmUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiICYmIChhZnRlciA9PT0gbnVsbCB8fCBhZnRlci50eXBlID09PSBcInNldFZhbHVlQXRUaW1lXCIpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2V2ZW50cy5nZXRCZWZvcmUoYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgbGV0IHByZXZpb3VzVmFsO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNWYWwgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbCA9IHByZXZpb3VzLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9leHBvbmVudGlhbEFwcHJvYWNoKGJlZm9yZS50aW1lLCBwcmV2aW91c1ZhbCwgYmVmb3JlLnZhbHVlLCBiZWZvcmUuY29uc3RhbnQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIiB8fCBhZnRlci50eXBlID09PSBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgbGV0IGJlZm9yZVZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICAgICAgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLl9ldmVudHMuZ2V0QmVmb3JlKGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlVmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBiZWZvcmVWYWx1ZSA9IHByZXZpb3VzLnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2xpbmVhckludGVycG9sYXRlKGJlZm9yZS50aW1lLCBiZWZvcmVWYWx1ZSwgYWZ0ZXIudGltZSwgYWZ0ZXIudmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZVZhbHVlLCBhZnRlci50aW1lLCBhZnRlci52YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodmFsdWUpO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGxldCBjdXJyZW50VmFsID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fZnJvbVR5cGUoY3VycmVudFZhbCkgPT09IDApIHtcbiAgICAgICAgICAgIGN1cnJlbnRWYWwgPSB0aGlzLl90b1R5cGUodGhpcy5fbWluT3V0cHV0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKGN1cnJlbnRWYWwsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhlbmRUaW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gbGluZWFyUmFtcFRvVmFsdWVBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShlbmRUaW1lKX1gKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICBsZXQgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyB0aGUgdmFsdWUgY2FuJ3QgYmUgMFxuICAgICAgICBudW1lcmljVmFsdWUgPSBFUShudW1lcmljVmFsdWUsIDApID8gdGhpcy5fbWluT3V0cHV0IDogbnVtZXJpY1ZhbHVlO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhlbmRUaW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KGVuZFRpbWUpfWApO1xuICAgICAgICAvLyBzdG9yZSB0aGUgZXZlbnRcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIiwgdmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSArIHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJhbXBUaW1lID0gdGhpcy50b1NlY29uZHMocmFtcFRpbWUpO1xuICAgICAgICBjb25zdCB0aW1lQ29uc3RhbnQgPSBNYXRoLmxvZyhyYW1wVGltZSArIDEpIC8gTWF0aC5sb2coMjAwKTtcbiAgICAgICAgdGhpcy5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIHRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIC8vIGF0IDkwJSBzdGFydCBhIGxpbmVhciByYW1wIHRvIHRoZSBmaW5hbCB2YWx1ZVxuICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSArIHJhbXBUaW1lICogMC45KTtcbiAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSArIHJhbXBUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBUaGUgdmFsdWUgd2lsbCBuZXZlciBiZSBhYmxlIHRvIGFwcHJvYWNoIHdpdGhvdXQgdGltZUNvbnN0YW50ID4gMC5cbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKHRpbWVDb25zdGFudCkgJiYgdGltZUNvbnN0YW50ID4gMCwgXCJ0aW1lQ29uc3RhbnQgbXVzdCBiZSBhIG51bWJlciBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gc2V0VGFyZ2V0QXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoc3RhcnRUaW1lKX1gKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICBjb25zdGFudDogdGltZUNvbnN0YW50LFxuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRUYXJnZXRBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcInNldFRhcmdldEF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRUYXJnZXRBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZyA9IDEpIHtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0aW5nVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZXNbMF0pICogc2NhbGluZztcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUoc3RhcnRpbmdWYWx1ZSksIHN0YXJ0VGltZSk7XG4gICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBkdXJhdGlvbiAvICh2YWx1ZXMubGVuZ3RoIC0gMSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZXNbaV0pICogc2NhbGluZztcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKG51bWVyaWNWYWx1ZSksIHN0YXJ0VGltZSArIGkgKiBzZWdUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudCB0byBjYW5jZWxTY2hlZHVsZWRWYWx1ZXM6ICR7SlNPTi5zdHJpbmdpZnkodGltZSl9YCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiY2FuY2VsU2NoZWR1bGVkVmFsdWVzXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHZhbHVlQXRUaW1lID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpKTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBzY2hlZHVsZSBldmVudHNcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50IHRvIGNhbmNlbEFuZEhvbGRBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodGltZSl9YCk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiY2FuY2VsQW5kSG9sZEF0VGltZVwiLCBjb21wdXRlZFRpbWUsIFwidmFsdWU9XCIgKyB2YWx1ZUF0VGltZSk7XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGV2ZW50IGF0IHRoZSBnaXZlbiBjb21wdXRlZFRpbWVcbiAgICAgICAgLy8gYW5kIHRoYXQgZXZlbiBpcyBub3QgYSBcInNldFwiXG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKGJlZm9yZSAmJiBFUShiZWZvcmUudGltZSwgY29tcHV0ZWRUaW1lKSkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGV2ZXJ5dGhpbmcgYWZ0ZXJcbiAgICAgICAgICAgIGlmIChhZnRlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhhZnRlci50aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoY29tcHV0ZWRUaW1lICsgdGhpcy5zYW1wbGVUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlcikge1xuICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgLy8gY2FuY2VsIHRoZSBuZXh0IGV2ZW50KHMpXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHZhbHVlQXRUaW1lKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZSh2YWx1ZUF0VGltZSksIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZUF0VGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlQXRUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgcmFtcFRvKHZhbHVlLCByYW1wVGltZSA9IDAuMSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBcImZyZXF1ZW5jeVwiIHx8IHRoaXMudW5pdHMgPT09IFwiYnBtXCIgfHwgdGhpcy51bml0cyA9PT0gXCJkZWNpYmVsc1wiKSB7XG4gICAgICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXBwbHkgYWxsIG9mIHRoZSBwcmV2aW91c2x5IHNjaGVkdWxlZCBldmVudHMgdG8gdGhlIHBhc3NlZCBpbiBQYXJhbSBvciBBdWRpb1BhcmFtLlxuICAgICAqIFRoZSBhcHBsaWVkIHZhbHVlcyB3aWxsIHN0YXJ0IGF0IHRoZSBjb250ZXh0J3MgY3VycmVudCB0aW1lIGFuZCBzY2hlZHVsZVxuICAgICAqIGFsbCBvZiB0aGUgZXZlbnRzIHdoaWNoIGFyZSBzY2hlZHVsZWQgb24gdGhpcyBQYXJhbSBvbnRvIHRoZSBwYXNzZWQgaW4gcGFyYW0uXG4gICAgICovXG4gICAgYXBwbHkocGFyYW0pIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAvLyBzZXQgdGhlIHBhcmFtJ3MgdmFsdWUgYXQgdGhlIGN1cnJlbnQgdGltZSBhbmQgc2NoZWR1bGUgZXZlcnl0aGluZyBlbHNlXG4gICAgICAgIHBhcmFtLnNldFZhbHVlQXRUaW1lKHRoaXMuZ2V0VmFsdWVBdFRpbWUobm93KSwgbm93KTtcbiAgICAgICAgLy8gaWYgdGhlIHByZXZpb3VzIGV2ZW50IHdhcyBhIGN1cnZlLCB0aGVuIHNldCB0aGUgcmVzdCBvZiBpdFxuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChub3cpO1xuICAgICAgICBpZiAocHJldmlvdXNFdmVudCAmJiBwcmV2aW91c0V2ZW50LnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgIC8vIGFwcHJveCBpdCB1bnRpbCB0aGUgbmV4dCBldmVudCB3aXRoIGxpbmVhciByYW1wc1xuICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHByZXZpb3VzRXZlbnQudGltZSk7XG4gICAgICAgICAgICAvLyBvciBmb3IgMiBzZWNvbmRzIGlmIHRoZXJlIGlzIG5vIGV2ZW50XG4gICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gbmV4dEV2ZW50ID8gbmV4dEV2ZW50LnRpbWUgOiBub3cgKyAyO1xuICAgICAgICAgICAgY29uc3Qgc3ViZGl2aXNpb25zID0gKGVuZFRpbWUgLSBub3cpIC8gMTA7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gbm93OyBpIDwgZW5kVGltZTsgaSArPSBzdWJkaXZpc2lvbnMpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLmdldFZhbHVlQXRUaW1lKGkpLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaEFmdGVyKHRoaXMuY29udGV4dC5jdXJyZW50VGltZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwiY2FuY2VsU2NoZWR1bGVkVmFsdWVzXCIpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudC50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgcGFyYW0uc2V0VGFyZ2V0QXRUaW1lKGV2ZW50LnZhbHVlLCBldmVudC50aW1lLCBldmVudC5jb25zdGFudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbVtldmVudC50eXBlXShldmVudC52YWx1ZSwgZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVwbGFjZSB0aGUgUGFyYW0ncyBpbnRlcm5hbCBBdWRpb1BhcmFtLiBXaWxsIGFwcGx5IHNjaGVkdWxlZCBjdXJ2ZXNcbiAgICAgKiBvbnRvIHRoZSBwYXJhbWV0ZXIgYW5kIHJlcGxhY2UgdGhlIGNvbm5lY3Rpb25zLlxuICAgICAqL1xuICAgIHNldFBhcmFtKHBhcmFtKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zd2FwcGFibGUsIFwiVGhlIFBhcmFtIG11c3QgYmUgYXNzaWduZWQgYXMgJ3N3YXBwYWJsZScgaW4gdGhlIGNvbnN0cnVjdG9yXCIpO1xuICAgICAgICBjb25zdCBpbnB1dCA9IHRoaXMuaW5wdXQ7XG4gICAgICAgIGlucHV0LmRpc2Nvbm5lY3QodGhpcy5fcGFyYW0pO1xuICAgICAgICB0aGlzLmFwcGx5KHBhcmFtKTtcbiAgICAgICAgdGhpcy5fcGFyYW0gPSBwYXJhbTtcbiAgICAgICAgaW5wdXQuY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgZGVmYXVsdFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdG9UeXBlKHRoaXMuX3BhcmFtLmRlZmF1bHRWYWx1ZSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0QVVUT01BVElPTiBDVVJWRSBDQUxDVUxBVElPTlNcbiAgICAvLyBcdE1JVCBMaWNlbnNlLCBjb3B5cmlnaHQgKGMpIDIwMTQgSm9yZGFuIFNhbnRlbGxcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDYWxjdWxhdGVzIHRoZSB0aGUgdmFsdWUgYWxvbmcgdGhlIGN1cnZlIHByb2R1Y2VkIGJ5IHNldFRhcmdldEF0VGltZVxuICAgIF9leHBvbmVudGlhbEFwcHJvYWNoKHQwLCB2MCwgdjEsIHRpbWVDb25zdGFudCwgdCkge1xuICAgICAgICByZXR1cm4gdjEgKyAodjAgLSB2MSkgKiBNYXRoLmV4cCgtKHQgLSB0MCkgLyB0aW1lQ29uc3RhbnQpO1xuICAgIH1cbiAgICAvLyBDYWxjdWxhdGVzIHRoZSB0aGUgdmFsdWUgYWxvbmcgdGhlIGN1cnZlIHByb2R1Y2VkIGJ5IGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXG4gICAgX2xpbmVhckludGVycG9sYXRlKHQwLCB2MCwgdDEsIHYxLCB0KSB7XG4gICAgICAgIHJldHVybiB2MCArICh2MSAtIHYwKSAqICgodCAtIHQwKSAvICh0MSAtIHQwKSk7XG4gICAgfVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVxuICAgIF9leHBvbmVudGlhbEludGVycG9sYXRlKHQwLCB2MCwgdDEsIHYxLCB0KSB7XG4gICAgICAgIHJldHVybiB2MCAqIE1hdGgucG93KHYxIC8gdjAsICh0IC0gdDApIC8gKHQxIC0gdDApKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4vVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQsIHdhcm4gfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBUb25lQXVkaW9Ob2RlIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBjbGFzc2VzIHdoaWNoIHByb2Nlc3MgYXVkaW8uXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9Ob2RlIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIHRoZSBjbGFzc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9Ob2RlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0IGFsbCBvZiB0aGUgbm9kZSB0aGF0IG11c3QgYmUgc2V0IHRvIG1hdGNoIHRoZSBDaGFubmVsUHJvcGVydGllc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGlucHV0cyBmZWVkaW5nIGludG8gdGhlIEF1ZGlvTm9kZS5cbiAgICAgKiBGb3Igc291cmNlIG5vZGVzLCB0aGlzIHdpbGwgYmUgMC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vZGUgPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2cobm9kZS5udW1iZXJPZklucHV0cyk7XG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb1BhcmFtKHRoaXMuaW5wdXQpIHx8IHRoaXMuaW5wdXQgaW5zdGFuY2VvZiBQYXJhbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG91dHB1dHMgb2YgdGhlIEF1ZGlvTm9kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vZGUgPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2cobm9kZS5udW1iZXJPZk91dHB1dHMpO1xuICAgICAqL1xuICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vdXRwdXQubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQVVESU8gUFJPUEVSVElFU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gZGVjaWRlIHdoaWNoIG5vZGVzIHRvIGdldC9zZXQgcHJvcGVydGllcyBvblxuICAgICAqL1xuICAgIF9pc0F1ZGlvTm9kZShub2RlKSB7XG4gICAgICAgIHJldHVybiBpc0RlZmluZWQobm9kZSkgJiYgKG5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlIHx8IGlzQXVkaW9Ob2RlKG5vZGUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBvZiB0aGUgYXVkaW8gbm9kZXMgKGVpdGhlciBpbnRlcm5hbCBvciBpbnB1dC9vdXRwdXQpIHdoaWNoIHRvZ2V0aGVyXG4gICAgICogbWFrZSB1cCBob3cgdGhlIGNsYXNzIG5vZGUgcmVzcG9uZHMgdG8gY2hhbm5lbCBpbnB1dC9vdXRwdXRcbiAgICAgKi9cbiAgICBfZ2V0SW50ZXJuYWxOb2RlcygpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9pbnRlcm5hbENoYW5uZWxzLnNsaWNlKDApO1xuICAgICAgICBpZiAodGhpcy5faXNBdWRpb05vZGUodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIG5vZGVMaXN0LnB1c2godGhpcy5pbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2lzQXVkaW9Ob2RlKHRoaXMub3V0cHV0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXQgIT09IHRoaXMub3V0cHV0KSB7XG4gICAgICAgICAgICAgICAgbm9kZUxpc3QucHVzaCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vZGVMaXN0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF1ZGlvIG9wdGlvbnMgZm9yIHRoaXMgbm9kZSBzdWNoIGFzIGNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAqIGNoYW5uZWxDb3VudCwgZXRjLlxuICAgICAqIEBwYXJhbSBvcHRpb25zXG4gICAgICovXG4gICAgX3NldENoYW5uZWxQcm9wZXJ0aWVzKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9nZXRJbnRlcm5hbE5vZGVzKCk7XG4gICAgICAgIG5vZGVMaXN0LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxDb3VudCA9IG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgbm9kZS5jaGFubmVsQ291bnRNb2RlID0gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgbm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBhdWRpbyBvcHRpb25zIGZvciB0aGlzIG5vZGUgc3VjaCBhcyBjaGFubmVsSW50ZXJwcmV0YXRpb25cbiAgICAgKiBjaGFubmVsQ291bnQsIGV0Yy5cbiAgICAgKi9cbiAgICBfZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKSB7XG4gICAgICAgIGNvbnN0IG5vZGVMaXN0ID0gdGhpcy5fZ2V0SW50ZXJuYWxOb2RlcygpO1xuICAgICAgICBhc3NlcnQobm9kZUxpc3QubGVuZ3RoID4gMCwgXCJUb25lQXVkaW9Ob2RlIGRvZXMgbm90IGhhdmUgYW55IGludGVybmFsIG5vZGVzXCIpO1xuICAgICAgICAvLyB1c2UgdGhlIGZpcnN0IG5vZGUgdG8gZ2V0IHByb3BlcnRpZXNcbiAgICAgICAgLy8gdGhleSBzaG91bGQgYWxsIGJlIHRoZSBzYW1lXG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2RlTGlzdFswXTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBub2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsQ291bnQgaXMgdGhlIG51bWJlciBvZiBjaGFubmVscyB1c2VkIHdoZW4gdXAtbWl4aW5nIGFuZCBkb3duLW1peGluZ1xuICAgICAqIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDIgZXhjZXB0IGZvclxuICAgICAqIHNwZWNpZmljIG5vZGVzIHdoZXJlIGl0cyB2YWx1ZSBpcyBzcGVjaWFsbHkgZGV0ZXJtaW5lZC5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsQ291bnQ7XG4gICAgfVxuICAgIHNldCBjaGFubmVsQ291bnQoY2hhbm5lbENvdW50KSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxDb3VudCB9KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxDb3VudE1vZGUgZGV0ZXJtaW5lcyBob3cgY2hhbm5lbHMgd2lsbCBiZSBjb3VudGVkIHdoZW4gdXAtbWl4aW5nIGFuZFxuICAgICAqIGRvd24tbWl4aW5nIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCJtYXhcIi4gVGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCBmb3Igbm9kZXMgd2l0aCBubyBpbnB1dHMuXG4gICAgICogKiBcIm1heFwiIC0gY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIHRoZSBtYXhpbXVtIG9mIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgb2YgYWxsIGNvbm5lY3Rpb25zIHRvIGFuIGlucHV0LiBJbiB0aGlzIG1vZGUgY2hhbm5lbENvdW50IGlzIGlnbm9yZWQuXG4gICAgICogKiBcImNsYW1wZWQtbWF4XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgZGV0ZXJtaW5lZCBhcyBmb3IgXCJtYXhcIiBhbmQgdGhlbiBjbGFtcGVkIHRvIGEgbWF4aW11bSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gY2hhbm5lbENvdW50LlxuICAgICAqICogXCJleHBsaWNpdFwiIC0gY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIHRoZSBleGFjdCB2YWx1ZSBhcyBzcGVjaWZpZWQgYnkgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbENvdW50TW9kZTtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxDb3VudE1vZGUoY2hhbm5lbENvdW50TW9kZSkge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsQ291bnRNb2RlIH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbEludGVycHJldGF0aW9uIGRldGVybWluZXMgaG93IGluZGl2aWR1YWwgY2hhbm5lbHMgd2lsbCBiZSB0cmVhdGVkXG4gICAgICogd2hlbiB1cC1taXhpbmcgYW5kIGRvd24tbWl4aW5nIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCJzcGVha2Vyc1wiLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbihjaGFubmVsSW50ZXJwcmV0YXRpb24pIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbEludGVycHJldGF0aW9uIH0pKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQ09OTkVDVElPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBjb25uZWN0IHRoZSBvdXRwdXQgb2YgYSBUb25lQXVkaW9Ob2RlIHRvIGFuIEF1ZGlvUGFyYW0sIEF1ZGlvTm9kZSwgb3IgVG9uZUF1ZGlvTm9kZVxuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgb3V0cHV0IHRvIGNvbm5lY3QgdG9cbiAgICAgKiBAcGFyYW0gb3V0cHV0TnVtIFRoZSBvdXRwdXQgdG8gY29ubmVjdCBmcm9tXG4gICAgICogQHBhcmFtIGlucHV0TnVtIFRoZSBpbnB1dCB0byBjb25uZWN0IHRvXG4gICAgICovXG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGNvbm5lY3QodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IHRvIHRoZSBjb250ZXh0J3MgZGVzdGluYXRpb24gbm9kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJDMlwiKS5zdGFydCgpO1xuICAgICAqIG9zYy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICovXG4gICAgdG9EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgdG8gdGhlIGNvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqIFNlZSBbW3RvRGVzdGluYXRpb25dXVxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgdG9NYXN0ZXIoKSB7XG4gICAgICAgIHdhcm4oXCJ0b01hc3RlcigpIGhhcyBiZWVuIHJlbmFtZWQgdG9EZXN0aW5hdGlvbigpXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGRpc2Nvbm5lY3QgdGhlIG91dHB1dFxuICAgICAqL1xuICAgIGRpc2Nvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICBkaXNjb25uZWN0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgdG8gdGhlIHJlc3Qgb2YgdGhlIG5vZGVzIGluIHNlcmllcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9kcnVtLXNhbXBsZXMvaGFuZGRydW0tbG9vcC5tcDNcIik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcig0KS5zdGFydCgpO1xuICAgICAqIGNvbnN0IGRpc3RvcnRpb24gPSBuZXcgVG9uZS5EaXN0b3J0aW9uKDAuNSk7XG4gICAgICogLy8gY29ubmVjdCB0aGUgcGxheWVyIHRvIHRoZSBmaWx0ZXIsIGRpc3RvcnRpb24gYW5kIHRoZW4gdG8gdGhlIG1hc3RlciBvdXRwdXRcbiAgICAgKiBwbGF5ZXIuY2hhaW4oZmlsdGVyLCBkaXN0b3J0aW9uLCBUb25lLkRlc3RpbmF0aW9uKTtcbiAgICAgKi9cbiAgICBjaGFpbiguLi5ub2Rlcykge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMsIC4uLm5vZGVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgdG8gdGhlIHJlc3Qgb2YgdGhlIG5vZGVzIGluIHBhcmFsbGVsLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9jb25nYS1yaHl0aG0ubXAzXCIpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqIGNvbnN0IHBpdGNoU2hpZnQgPSBuZXcgVG9uZS5QaXRjaFNoaWZ0KDQpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoXCJHNVwiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gY29ubmVjdCBhIG5vZGUgdG8gdGhlIHBpdGNoIHNoaWZ0IGFuZCBmaWx0ZXIgaW4gcGFyYWxsZWxcbiAgICAgKiBwbGF5ZXIuZmFuKHBpdGNoU2hpZnQsIGZpbHRlcik7XG4gICAgICovXG4gICAgZmFuKC4uLm5vZGVzKSB7XG4gICAgICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB0aGlzLmNvbm5lY3Qobm9kZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcG9zZSBhbmQgZGlzY29ubmVjdFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXQgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZSh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vdXRwdXQgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdXRwdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBDT05ORUNUSU9OU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIGNvbm5lY3QgdG9nZXRoZXIgYWxsIG9mIHRoZSBhcmd1bWVudHMgaW4gc2VyaWVzXG4gKiBAcGFyYW0gbm9kZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpIHtcbiAgICBjb25zdCBmaXJzdCA9IG5vZGVzLnNoaWZ0KCk7XG4gICAgbm9kZXMucmVkdWNlKChwcmV2LCBjdXJyZW50KSA9PiB7XG4gICAgICAgIGlmIChwcmV2IGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgcHJldi5jb25uZWN0KGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHByZXYpKSB7XG4gICAgICAgICAgICBjb25uZWN0KHByZXYsIGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdXJyZW50O1xuICAgIH0sIGZpcnN0KTtcbn1cbi8qKlxuICogQ29ubmVjdCB0d28gbm9kZXMgdG9nZXRoZXIgc28gdGhhdCBzaWduYWwgZmxvd3MgZnJvbSB0aGVcbiAqIGZpcnN0IG5vZGUgdG8gdGhlIHNlY29uZC4gT3B0aW9uYWxseSBzcGVjaWZ5IHRoZSBpbnB1dCBhbmQgb3V0cHV0IGNoYW5uZWxzLlxuICogQHBhcmFtIHNyY05vZGUgVGhlIHNvdXJjZSBub2RlXG4gKiBAcGFyYW0gZHN0Tm9kZSBUaGUgZGVzdGluYXRpb24gbm9kZVxuICogQHBhcmFtIG91dHB1dE51bWJlciBUaGUgb3V0cHV0IGNoYW5uZWwgb2YgdGhlIHNyY05vZGVcbiAqIEBwYXJhbSBpbnB1dE51bWJlciBUaGUgaW5wdXQgY2hhbm5lbCBvZiB0aGUgZHN0Tm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdChzcmNOb2RlLCBkc3ROb2RlLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKHNyY05vZGUpLCBcIkNhbm5vdCBjb25uZWN0IGZyb20gdW5kZWZpbmVkIG5vZGVcIik7XG4gICAgYXNzZXJ0KGlzRGVmaW5lZChkc3ROb2RlKSwgXCJDYW5ub3QgY29ubmVjdCB0byB1bmRlZmluZWQgbm9kZVwiKTtcbiAgICBpZiAoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgaXNBdWRpb05vZGUoZHN0Tm9kZSkpIHtcbiAgICAgICAgYXNzZXJ0KGRzdE5vZGUubnVtYmVyT2ZJbnB1dHMgPiAwLCBcIkNhbm5vdCBjb25uZWN0IHRvIG5vZGUgd2l0aCBubyBpbnB1dHNcIik7XG4gICAgfVxuICAgIGFzc2VydChzcmNOb2RlLm51bWJlck9mT3V0cHV0cyA+IDAsIFwiQ2Fubm90IGNvbm5lY3QgZnJvbSBub2RlIHdpdGggbm8gb3V0cHV0c1wiKTtcbiAgICAvLyByZXNvbHZlIHRoZSBpbnB1dCBvZiB0aGUgZHN0Tm9kZVxuICAgIHdoaWxlICgoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgZHN0Tm9kZSBpbnN0YW5jZW9mIFBhcmFtKSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKGRzdE5vZGUuaW5wdXQpKSB7XG4gICAgICAgICAgICBkc3ROb2RlID0gZHN0Tm9kZS5pbnB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoc3JjTm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChzcmNOb2RlLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHNyY05vZGUgPSBzcmNOb2RlLm91dHB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBtYWtlIHRoZSBjb25uZWN0aW9uXG4gICAgaWYgKGlzQXVkaW9QYXJhbShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmNvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNyY05vZGUuY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICB9XG59XG4vKipcbiAqIERpc2Nvbm5lY3QgYSBub2RlIGZyb20gYWxsIG5vZGVzIG9yIG9wdGlvbmFsbHkgaW5jbHVkZSBhIGRlc3RpbmF0aW9uIG5vZGUgYW5kIGlucHV0L291dHB1dCBjaGFubmVscy5cbiAqIEBwYXJhbSBzcmNOb2RlIFRoZSBzb3VyY2Ugbm9kZVxuICogQHBhcmFtIGRzdE5vZGUgVGhlIGRlc3RpbmF0aW9uIG5vZGVcbiAqIEBwYXJhbSBvdXRwdXROdW1iZXIgVGhlIG91dHB1dCBjaGFubmVsIG9mIHRoZSBzcmNOb2RlXG4gKiBAcGFyYW0gaW5wdXROdW1iZXIgVGhlIGlucHV0IGNoYW5uZWwgb2YgdGhlIGRzdE5vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2Nvbm5lY3Qoc3JjTm9kZSwgZHN0Tm9kZSwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgLy8gcmVzb2x2ZSB0aGUgZGVzdGluYXRpb24gbm9kZVxuICAgIGlmIChpc0RlZmluZWQoZHN0Tm9kZSkpIHtcbiAgICAgICAgd2hpbGUgKGRzdE5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICBkc3ROb2RlID0gZHN0Tm9kZS5pbnB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyByZXNvbHZlIHRoZSBzcmMgbm9kZVxuICAgIHdoaWxlICghKGlzQXVkaW9Ob2RlKHNyY05vZGUpKSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHNyY05vZGUub3V0cHV0KSkge1xuICAgICAgICAgICAgc3JjTm9kZSA9IHNyY05vZGUub3V0cHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0F1ZGlvUGFyYW0oZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuZGlzY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNyY05vZGUuZGlzY29ubmVjdCgpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb05vZGUuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgTmF0aXZlIFdlYiBBdWRpbyBHYWluTm9kZS5cbiAqIFRoZSBHYWluTm9kZSBpcyBhIGJhc2ljIGJ1aWxkaW5nIGJsb2NrIG9mIHRoZSBXZWIgQXVkaW9cbiAqIEFQSSBhbmQgaXMgdXNlZnVsIGZvciByb3V0aW5nIGF1ZGlvIGFuZCBhZGp1c3RpbmcgZ2FpbnMuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBnYWluTm9kZSA9IG5ldyBUb25lLkdhaW4oMCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDMwKS5jb25uZWN0KGdhaW5Ob2RlKS5zdGFydCgpO1xuICogXHRnYWluTm9kZS5nYWluLnJhbXBUbygxLCAwLjEpO1xuICogXHRnYWluTm9kZS5nYWluLnJhbXBUbygwLCAwLjQsIDAuMik7XG4gKiB9LCAwLjcsIDEpO1xuICovXG5leHBvcnQgY2xhc3MgR2FpbiBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhHYWluLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZ2FpblwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR2FpblwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHdyYXBwZWQgR2Fpbk5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIC8vIGlucHV0ID0gb3V0cHV0XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhaW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJnYWluXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLmdhaW4gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2dhaW5Ob2RlLmdhaW4sXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJnYWluXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIGdhaW46IDEsXG4gICAgICAgICAgICB1bml0czogXCJnYWluXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2Fpbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlLCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGZpcmUtYW5kLWZvcmdldCBub2Rlc1xuICovXG5leHBvcnQgY2xhc3MgT25lU2hvdFNvdXJjZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGFmdGVyIHRoZVxuICAgICAgICAgKiBzb3VyY2UgaXMgZG9uZSBwbGF5aW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbmVuZGVkID0gbm9PcDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzdGFydCB0aW1lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzdG9wIHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaWQgb2YgdGhlIHRpbWVvdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwdWJsaWMgb3V0cHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IGdhaW4gbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5vdXRwdXQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmdldFN0YXRlQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEgJiZcbiAgICAgICAgICAgICAgICBjb21wdXRlZFRpbWUgPj0gdGhpcy5fc3RhcnRUaW1lICYmXG4gICAgICAgICAgICAgICAgKHRoaXMuX3N0b3BUaW1lID09PSAtMSB8fCBjb21wdXRlZFRpbWUgPD0gdGhpcy5fc3RvcFRpbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RhcnRlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RvcHBlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICAgICAgdGhpcy5fY3VydmUgPSBvcHRpb25zLmN1cnZlO1xuICAgICAgICB0aGlzLm9uZW5kZWQgPSBvcHRpb25zLm9uZW5kZWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBvbmVuZGVkOiBub09wLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHNvdXJjZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0YXJ0IHRoZSBzb3VyY2VcbiAgICAgKi9cbiAgICBfc3RhcnRHYWluKHRpbWUsIGdhaW4gPSAxKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgPT09IC0xLCBcIlNvdXJjZSBjYW5ub3QgYmUgc3RhcnRlZCBtb3JlIHRoYW4gb25jZVwiKTtcbiAgICAgICAgLy8gYXBwbHkgYSBmYWRlIGluIGVudmVsb3BlXG4gICAgICAgIGNvbnN0IGZhZGVJblRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLl9mYWRlSW4pO1xuICAgICAgICAvLyByZWNvcmQgdGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gdGltZSArIGZhZGVJblRpbWU7XG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IE1hdGgubWF4KHRoaXMuX3N0YXJ0VGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIGVudmVsb3BlXG4gICAgICAgIGlmIChmYWRlSW5UaW1lID4gMCkge1xuICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoZ2FpbiwgdGltZSArIGZhZGVJblRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoZ2FpbiwgdGltZSwgZmFkZUluVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKGdhaW4sIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBzb3VyY2Ugbm9kZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRvIHN0b3AgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgdGltZSk7XG4gICAgICAgIHRoaXMuX3N0b3BHYWluKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0b3AgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIF9zdG9wR2Fpbih0aW1lKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgIT09IC0xLCBcIidzdGFydCcgbXVzdCBiZSBjYWxsZWQgYmVmb3JlICdzdG9wJ1wiKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBwcmV2aW91cyBzdG9wXG4gICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuICAgICAgICAvLyB0aGUgZmFkZU91dCB0aW1lXG4gICAgICAgIGNvbnN0IGZhZGVPdXRUaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5fZmFkZU91dCk7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBzdG9wIGNhbGxiYWNrXG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gdGhpcy50b1NlY29uZHModGltZSkgKyBmYWRlT3V0VGltZTtcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSBNYXRoLm1heCh0aGlzLl9zdG9wVGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgaWYgKGZhZGVPdXRUaW1lID4gMCkge1xuICAgICAgICAgICAgLy8gc3RhcnQgdGhlIGZhZGUgb3V0IGN1cnZlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmxpbmVhclJhbXBUbygwLCBmYWRlT3V0VGltZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnRhcmdldFJhbXBUbygwLCBmYWRlT3V0VGltZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzdG9wIGFueSBvbmdvaW5nIHJhbXBzLCBhbmQgc2V0IHRoZSB2YWx1ZSB0byAwXG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBhbGxvdyBhZGRpdGlvbmFsIHRpbWUgZm9yIHRoZSBleHBvbmVudGlhbCBjdXJ2ZSB0byBmdWxseSBkZWNheVxuICAgICAgICAgICAgY29uc3QgYWRkaXRpb25hbFRhaWwgPSB0aGlzLl9jdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiID8gZmFkZU91dFRpbWUgKiAyIDogMDtcbiAgICAgICAgICAgIHRoaXMuX3N0b3BTb3VyY2UodGhpcy5ub3coKSArIGFkZGl0aW9uYWxUYWlsKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQoKTtcbiAgICAgICAgfSwgdGhpcy5fc3RvcFRpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBvbmVuZGVkIGNhbGxiYWNrXG4gICAgICovXG4gICAgX29uZW5kZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uZW5kZWQgIT09IG5vT3ApIHtcbiAgICAgICAgICAgIHRoaXMub25lbmRlZCh0aGlzKTtcbiAgICAgICAgICAgIC8vIG92ZXJ3cml0ZSBvbmVuZGVkIHRvIG1ha2Ugc3VyZSBpdCBvbmx5IGlzIGNhbGxlZCBvbmNlXG4gICAgICAgICAgICB0aGlzLm9uZW5kZWQgPSBub09wO1xuICAgICAgICAgICAgLy8gZGlzcG9zZSB3aGVuIGl0J3MgZW5kZWQgdG8gZnJlZSB1cCBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uIG9ubHkgaW4gdGhlIG9ubGluZSBjb250ZXh0XG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGV4dC5pc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwb3NlQ2FsbGJhY2sgPSAoKSA9PiB0aGlzLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cucmVxdWVzdElkbGVDYWxsYmFjayAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrKGRpc3Bvc2VDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGRpc3Bvc2VDYWxsYmFjaywgMTAwMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhlIGN1cnJlbnQgdGltZVxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhIHNjaGVkdWxlZCBzdG9wIGV2ZW50XG4gICAgICovXG4gICAgY2FuY2VsU3RvcCgpIHtcbiAgICAgICAgdGhpcy5sb2coXCJjYW5jZWxTdG9wXCIpO1xuICAgICAgICBhc3NlcnQodGhpcy5fc3RhcnRUaW1lICE9PSAtMSwgXCJTb3VyY2UgaXMgbm90IHN0YXJ0ZWRcIik7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgc3RvcCBlbnZlbG9wZVxuICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLl9zdGFydFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IC0xO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9uZVNob3RTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL09uZVNob3RTb3VyY2VcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgQ29uc3RhbnRTb3VyY2UuXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHJlc2NoZWR1bGUgdGhlIHN0b3AgbWV0aG9kLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgVG9uZUNvbnN0YW50U291cmNlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVDb25zdGFudFNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9mZnNldFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVDb25zdGFudFNvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNpZ25hbCBnZW5lcmF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUNvbnN0YW50U291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib2Zmc2V0XCJdKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zb3VyY2UsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3NvdXJjZS5vZmZzZXQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9mZnNldCxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIG9mZnNldDogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHNvdXJjZSBub2RlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3N0b3BTb3VyY2UodGltZSkge1xuICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMub2Zmc2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUNvbnN0YW50U291cmNlLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUb25lQ29uc3RhbnRTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQ29uc3RhbnRTb3VyY2VcIjtcbi8qKlxuICogQSBzaWduYWwgaXMgYW4gYXVkaW8tcmF0ZSB2YWx1ZS4gVG9uZS5TaWduYWwgaXMgYSBjb3JlIGNvbXBvbmVudCBvZiB0aGUgbGlicmFyeS5cbiAqIFVubGlrZSBhIG51bWJlciwgU2lnbmFscyBjYW4gYmUgc2NoZWR1bGVkIHdpdGggc2FtcGxlLWxldmVsIGFjY3VyYWN5LiBUb25lLlNpZ25hbFxuICogaGFzIGFsbCBvZiB0aGUgbWV0aG9kcyBhdmFpbGFibGUgdG8gbmF0aXZlIFdlYiBBdWRpb1xuICogW0F1ZGlvUGFyYW1dKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWF1ZGlvcGFyYW0taW50ZXJmYWNlKVxuICogYXMgd2VsbCBhcyBhZGRpdGlvbmFsIGNvbnZlbmllbmNlcy4gUmVhZCBtb3JlIGFib3V0IHdvcmtpbmcgd2l0aCBzaWduYWxzXG4gKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL1RvbmVqcy9Ub25lLmpzL3dpa2kvU2lnbmFscykuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIGEgc2NoZWR1bGVhYmxlIHNpZ25hbCB3aGljaCBjYW4gYmUgY29ubmVjdGVkIHRvIGNvbnRyb2wgYW4gQXVkaW9QYXJhbSBvciBhbm90aGVyIFNpZ25hbFxuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKHtcbiAqIFx0dmFsdWU6IFwiQzRcIixcbiAqIFx0dW5pdHM6IFwiZnJlcXVlbmN5XCJcbiAqIH0pLmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG4gKiAvLyB0aGUgc2NoZWR1bGVkIHJhbXAgY29udHJvbHMgdGhlIGNvbm5lY3RlZCBzaWduYWxcbiAqIHNpZ25hbC5yYW1wVG8oXCJDMlwiLCA0LCBcIiswLjVcIik7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWwgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNpZ25hbFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUgb3ZlcnJpZGRlbiBvbiBjb25uZWN0aW9uLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IHRydWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9jb25zdGFudFNvdXJjZSA9IG5ldyBUb25lQ29uc3RhbnRTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zLnZhbHVlLFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uuc3RhcnQoMCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIC8vIHN0YXJ0IGl0IG9ubHkgd2hlbiBjb25uZWN0ZWQgdG8gc29tZXRoaW5nXG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJhbS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFCU1RSQUNUIFBBUkFNIElOVEVSRkFDRVxuICAgIC8vIGp1c3QgYSBwcm94eSBmb3IgdGhlIENvbnN0YW50U291cmNlTm9kZSdzIG9mZnNldCBBdWRpb1BhcmFtXG4gICAgLy8gYWxsIGRvY3MgYXJlIGdlbmVyYXRlZCBmcm9tIEFic3RyYWN0UGFyYW0udHNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0UmFtcFBvaW50KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgcmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS52YWx1ZTtcbiAgICB9XG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGdldCBjb252ZXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uY29udmVydDtcbiAgICB9XG4gICAgc2V0IGNvbnZlcnQoY29udmVydCkge1xuICAgICAgICB0aGlzLl9wYXJhbS5jb252ZXJ0ID0gY29udmVydDtcbiAgICB9XG4gICAgZ2V0IHVuaXRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udW5pdHM7XG4gICAgfVxuICAgIGdldCBvdmVycmlkZGVuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ub3ZlcnJpZGRlbjtcbiAgICB9XG4gICAgc2V0IG92ZXJyaWRkZW4ob3ZlcnJpZGRlbikge1xuICAgICAgICB0aGlzLl9wYXJhbS5vdmVycmlkZGVuID0gb3ZlcnJpZGRlbjtcbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWF4VmFsdWU7XG4gICAgfVxuICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1pblZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWUgW1tQYXJhbS5hcHBseV1dLlxuICAgICAqL1xuICAgIGFwcGx5KHBhcmFtKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmFwcGx5KHBhcmFtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBXaGVuIGNvbm5lY3RpbmcgZnJvbSBhIHNpZ25hbCwgaXQncyBuZWNlc3NhcnkgdG8gemVybyBvdXQgdGhlIG5vZGUgZGVzdGluYXRpb25cbiAqIG5vZGUgaWYgdGhhdCBub2RlIGlzIGFsc28gYSBzaWduYWwuIElmIHRoZSBkZXN0aW5hdGlvbiBpcyBub3QgMCwgdGhlbiB0aGUgdmFsdWVzXG4gKiB3aWxsIGJlIHN1bW1lZC4gVGhpcyBtZXRob2QgaW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgb2YgdGhlIGRlc3RpbmF0aW9uIHNpZ25hbCB3aWxsXG4gKiBiZSB0aGUgc2FtZSBhcyB0aGUgc291cmNlIHNpZ25hbCwgbWFraW5nIHRoZSBkZXN0aW5hdGlvbiBzaWduYWwgYSBwYXNzIHRocm91Z2ggbm9kZS5cbiAqIEBwYXJhbSBzaWduYWwgVGhlIG91dHB1dCBzaWduYWwgdG8gY29ubmVjdCBmcm9tXG4gKiBAcGFyYW0gZGVzdGluYXRpb24gdGhlIGRlc3RpbmF0aW9uIHRvIGNvbm5lY3QgdG9cbiAqIEBwYXJhbSBvdXRwdXROdW0gdGhlIG9wdGlvbmFsIG91dHB1dCBudW1iZXJcbiAqIEBwYXJhbSBpbnB1dE51bSB0aGUgaW5wdXQgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0U2lnbmFsKHNpZ25hbCwgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pIHtcbiAgICBpZiAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBQYXJhbSB8fCBpc0F1ZGlvUGFyYW0oZGVzdGluYXRpb24pIHx8XG4gICAgICAgIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFNpZ25hbCAmJiBkZXN0aW5hdGlvbi5vdmVycmlkZSkpIHtcbiAgICAgICAgLy8gY2FuY2VsIGNoYW5nZXNcbiAgICAgICAgZGVzdGluYXRpb24uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKDApO1xuICAgICAgICAvLyByZXNldCB0aGUgdmFsdWVcbiAgICAgICAgZGVzdGluYXRpb24uc2V0VmFsdWVBdFRpbWUoMCwgMCk7XG4gICAgICAgIC8vIG1hcmsgdGhlIHZhbHVlIGFzIG92ZXJyaWRkZW5cbiAgICAgICAgaWYgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgU2lnbmFsKSB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvbi5vdmVycmlkZGVuID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25uZWN0KHNpZ25hbCwgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2lnbmFsLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogQSBQYXJhbSBjbGFzcyBqdXN0IGZvciBjb21wdXRpbmcgdGlja3MuIFNpbWlsYXIgdG8gdGhlIFtbUGFyYW1dXSBjbGFzcyxcbiAqIGJ1dCBvZmZlcnMgY29udmVyc2lvbiB0byBCUE0gdmFsdWVzIGFzIHdlbGwgYXMgYWJpbGl0eSB0byBjb21wdXRlIHRpY2tcbiAqIGR1cmF0aW9uIGFuZCBlbGFwc2VkIHRpY2tzXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrUGFyYW0gZXh0ZW5kcyBQYXJhbSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tQYXJhbS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1BhcmFtXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZWxpbmUgd2hpY2ggdHJhY2tzIGFsbCBvZiB0aGUgYXV0b21hdGlvbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoSW5maW5pdHkpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGludGVybmFsIGhvbGRlciBmb3IgdGhlIG11bHRpcGxpZXIgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSAxO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1BhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICAvLyBzZXQgdGhlIG11bHRpcGxpZXJcbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IG9wdGlvbnMubXVsdGlwbGllcjtcbiAgICAgICAgLy8gY2xlYXIgdGhlIHRpY2tzIGZyb20gdGhlIGJlZ2lubmluZ1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKDApO1xuICAgICAgICAvLyBzZXQgYW4gaW5pdGlhbCBldmVudFxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpY2tzOiAwLFxuICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLl9mcm9tVHlwZShvcHRpb25zLnZhbHVlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oUGFyYW0uZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXVsdGlwbGllcjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgY29uc3RhbnQpIHtcbiAgICAgICAgLy8gYXBwcm94aW1hdGUgaXQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHNcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludCh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gc3RhcnQgZnJvbSBwcmV2aW91c2x5IHNjaGVkdWxlZCB2YWx1ZVxuICAgICAgICBjb25zdCBwcmV2RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IE1hdGgucm91bmQoTWF0aC5tYXgoMSAvIGNvbnN0YW50LCAxKSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBjb25zdGFudCAqIGkgKyB0aW1lO1xuICAgICAgICAgICAgY29uc3QgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2gocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgY29tcHV0ZWRWYWx1ZSwgY29uc3RhbnQsIHNlZ1RpbWUpO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUocmFtcFZhbCksIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgY29uc3QgdGlja3NVbnRpbFRpbWUgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgZXZlbnQudGlja3MgPSBNYXRoLm1heCh0aWNrc1VudGlsVGltZSwgMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgc3VwZXIubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgY29uc3QgdGlja3NVbnRpbFRpbWUgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgZXZlbnQudGlja3MgPSBNYXRoLm1heCh0aWNrc1VudGlsVGltZSwgMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIC8vIGFwcm94aW1hdGUgaXQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHNcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFZhbCA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gc3RhcnQgZnJvbSBwcmV2aW91c2x5IHNjaGVkdWxlZCB2YWx1ZVxuICAgICAgICBjb25zdCBwcmV2RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICAvLyBhcHByb3ggMTAgc2VnbWVudHMgcGVyIHNlY29uZFxuICAgICAgICBjb25zdCBzZWdtZW50cyA9IE1hdGgucm91bmQoTWF0aC5tYXgoKHRpbWUgLSBwcmV2RXZlbnQudGltZSkgKiAxMCwgMSkpO1xuICAgICAgICBjb25zdCBzZWdtZW50RHVyID0gKCh0aW1lIC0gcHJldkV2ZW50LnRpbWUpIC8gc2VnbWVudHMpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBzZWdtZW50czsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWdUaW1lID0gc2VnbWVudER1ciAqIGkgKyBwcmV2RXZlbnQudGltZTtcbiAgICAgICAgICAgIGNvbnN0IHJhbXBWYWwgPSB0aGlzLl9leHBvbmVudGlhbEludGVycG9sYXRlKHByZXZFdmVudC50aW1lLCBwcmV2RXZlbnQudmFsdWUsIHRpbWUsIGNvbXB1dGVkVmFsLCBzZWdUaW1lKTtcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHJhbXBWYWwpLCBzZWdUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGljayB2YWx1ZSBhdCB0aGUgdGltZS4gVGFrZXMgaW50byBhY2NvdW50XG4gICAgICogYW55IGF1dG9tYXRpb24gY3VydmVzIHNjaGVkdWxlZCBvbiB0aGUgc2lnbmFsLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgVGhlIHRpbWUgdG8gZ2V0IHRoZSB0aWNrIGNvdW50IGF0XG4gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRpY2tzIHdoaWNoIGhhdmUgZWxhcHNlZCBhdCB0aGUgdGltZSBnaXZlbiBhbnkgYXV0b21hdGlvbnMuXG4gICAgICovXG4gICAgX2dldFRpY2tzVW50aWxFdmVudChldmVudCwgdGltZSkge1xuICAgICAgICBpZiAoZXZlbnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIHRpY2tzOiAwLFxuICAgICAgICAgICAgICAgIHRpbWU6IDAsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1VuZGVmKGV2ZW50LnRpY2tzKSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGV2ZW50LnRpY2tzID0gdGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KHByZXZpb3VzRXZlbnQsIGV2ZW50LnRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbDAgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGV2ZW50LnRpbWUpKTtcbiAgICAgICAgbGV0IHZhbDEgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpKTtcbiAgICAgICAgLy8gaWYgaXQncyByaWdodCBvbiB0aGUgbGluZSwgdGFrZSB0aGUgcHJldmlvdXMgdmFsdWVcbiAgICAgICAgY29uc3Qgb25UaGVMaW5lRXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICBpZiAob25UaGVMaW5lRXZlbnQgJiYgb25UaGVMaW5lRXZlbnQudGltZSA9PT0gdGltZSAmJiBvblRoZUxpbmVFdmVudC50eXBlID09PSBcInNldFZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgIHZhbDEgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMC41ICogKHRpbWUgLSBldmVudC50aW1lKSAqICh2YWwwICsgdmFsMSkgKyBldmVudC50aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGljayB2YWx1ZSBhdCB0aGUgdGltZS4gVGFrZXMgaW50byBhY2NvdW50XG4gICAgICogYW55IGF1dG9tYXRpb24gY3VydmVzIHNjaGVkdWxlZCBvbiB0aGUgc2lnbmFsLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBnZXQgdGhlIHRpY2sgY291bnQgYXRcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChldmVudCwgY29tcHV0ZWRUaW1lKSwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCB0aW1lIG9mIHRoZSBudW1iZXIgb2YgdGlja3MgZnJvbSB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSB0aWNrcyBUaGUgbnVtYmVyIG9mIHRpY2tzIHRvIGNhbGN1bGF0ZVxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBnZXQgdGhlIG5leHQgdGljayBmcm9tXG4gICAgICogQHJldHVybiBUaGUgZHVyYXRpb24gb2YgdGhlIG51bWJlciBvZiB0aWNrcyBmcm9tIHRoZSBnaXZlbiB0aW1lIGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaWNrID0gdGhpcy5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIHRpY2tzKSAtIGNvbXB1dGVkVGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSB0aWNrLCByZXR1cm5zIHRoZSB0aW1lIHRoYXQgdGljayBvY2N1cnMgYXQuXG4gICAgICogQHJldHVybiBUaGUgdGltZSB0aGF0IHRoZSB0aWNrIG9jY3Vycy5cbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2spIHtcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldCh0aWNrLCBcInRpY2tzXCIpO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcih0aWNrLCBcInRpY2tzXCIpO1xuICAgICAgICBpZiAoYmVmb3JlICYmIGJlZm9yZS50aWNrcyA9PT0gdGljaykge1xuICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJlZm9yZSAmJiBhZnRlciAmJlxuICAgICAgICAgICAgYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiICYmXG4gICAgICAgICAgICBiZWZvcmUudmFsdWUgIT09IGFmdGVyLnZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwwID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShiZWZvcmUudGltZSkpO1xuICAgICAgICAgICAgY29uc3QgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoYWZ0ZXIudGltZSkpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGEgPSAodmFsMSAtIHZhbDApIC8gKGFmdGVyLnRpbWUgLSBiZWZvcmUudGltZSk7XG4gICAgICAgICAgICBjb25zdCBrID0gTWF0aC5zcXJ0KE1hdGgucG93KHZhbDAsIDIpIC0gMiAqIGRlbHRhICogKGJlZm9yZS50aWNrcyAtIHRpY2spKTtcbiAgICAgICAgICAgIGNvbnN0IHNvbDEgPSAoLXZhbDAgKyBrKSAvIGRlbHRhO1xuICAgICAgICAgICAgY29uc3Qgc29sMiA9ICgtdmFsMCAtIGspIC8gZGVsdGE7XG4gICAgICAgICAgICByZXR1cm4gKHNvbDEgPiAwID8gc29sMSA6IHNvbDIpICsgYmVmb3JlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlKSB7XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS50aW1lICsgKHRpY2sgLSBiZWZvcmUudGlja3MpIC8gYmVmb3JlLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRpY2sgLyB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBzb21lIG51bWJlciBvZiB0aWNrcyB0aGVpciB0aGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhY2NvdW50aW5nXG4gICAgICogZm9yIGFueSBhdXRvbWF0aW9uIGN1cnZlcyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY29udmVydCB0byBzZWNvbmRzLlxuICAgICAqIEBwYXJhbSAgd2hlbiAgV2hlbiBhbG9uZyB0aGUgYXV0b21hdGlvbiB0aW1lbGluZSB0byBjb252ZXJ0IHRoZSB0aWNrcy5cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIG9mIHRoZSB0aWNrcy5cbiAgICAgKi9cbiAgICB0aWNrc1RvVGltZSh0aWNrcywgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHdoZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBbW3RpY2tzVG9UaW1lXV0uIENvbnZlcnQgYSBkdXJhdGlvbiBpblxuICAgICAqIHNlY29uZHMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgbnVtYmVyIG9mIHRpY2tzIGFjY291bnRpbmcgZm9yIGFueVxuICAgICAqIGF1dG9tYXRpb24gY3VydmVzIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gVGhlIHRpbWUgaW50ZXJ2YWwgdG8gY29udmVydCB0byB0aWNrcy5cbiAgICAgKiBAcGFyYW0gIHdoZW4gV2hlbiBhbG9uZyB0aGUgYXV0b21hdGlvbiB0aW1lbGluZSB0byBjb252ZXJ0IHRoZSB0aWNrcy5cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBpbiB0aWNrcy5cbiAgICAgKi9cbiAgICB0aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgY29uc3Qgc3RhcnRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgZW5kVGlja3MgPSB0aGlzLmdldFRpY2tzQXRUaW1lKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gZW5kVGlja3MgLSBzdGFydFRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGZyb20gdGhlIHR5cGUgd2hlbiB0aGUgdW5pdCB2YWx1ZSBpcyBCUE1cbiAgICAgKi9cbiAgICBfZnJvbVR5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBcImJwbVwiICYmIHRoaXMubXVsdGlwbGllcikge1xuICAgICAgICAgICAgcmV0dXJuIDEgLyAoNjAgLyB2YWwgLyB0aGlzLm11bHRpcGxpZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLl9mcm9tVHlwZSh2YWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNwZWNpYWwgY2FzZSBvZiB0eXBlIGNvbnZlcnNpb24gd2hlcmUgdGhlIHVuaXRzID09PSBcImJwbVwiXG4gICAgICovXG4gICAgX3RvVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiYnBtXCIgJiYgdGhpcy5tdWx0aXBsaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gKHZhbCAvIHRoaXMubXVsdGlwbGllcikgKiA2MDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdXBlci5fdG9UeXBlKHZhbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtdWx0aXBsaWVyIG9uIHRoZSBicG0gdmFsdWUuIFVzZWZ1bCBmb3Igc2V0dGluZyBhIFBQUSByZWxhdGl2ZSB0byB0aGUgYmFzZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IG11bHRpcGxpZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgbXVsdGlwbGllcihtKSB7XG4gICAgICAgIC8vIGdldCBhbmQgcmVzZXQgdGhlIGN1cnJlbnQgdmFsdWUgd2l0aCB0aGUgbmV3IG11bHRpcGxpZXJcbiAgICAgICAgLy8gbWlnaHQgYmUgbmVjZXNzYXJ5IHRvIGNsZWFyIGFsbCB0aGUgcHJldmlvdXMgdmFsdWVzXG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWwgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gbTtcbiAgICAgICAgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgMCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1BhcmFtLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaWNrUGFyYW0gfSBmcm9tIFwiLi9UaWNrUGFyYW1cIjtcbi8qKlxuICogVGlja1NpZ25hbCBleHRlbmRzIFRvbmUuU2lnbmFsLCBidXQgYWRkcyB0aGUgY2FwYWJpbGl0eVxuICogdG8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgZWxhcHNlZCB0aWNrcy4gZXhwb25lbnRpYWwgYW5kIHRhcmdldCBjdXJ2ZXNcbiAqIGFyZSBhcHByb3hpbWF0ZWQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHMuXG4gKlxuICogVGhhbmsgeW91IEJydW5vIERpYXMsIEguIFNvZmlhIFBpbnRvLCBhbmQgRGF2aWQgTS4gTWF0b3MsXG4gKiBmb3IgeW91ciBbV0FDIHBhcGVyXShodHRwczovL3NtYXJ0ZWNoLmdhdGVjaC5lZHUvYml0c3RyZWFtL2hhbmRsZS8xODUzLzU0NTg4L1dBQzIwMTYtNDkucGRmKVxuICogZGVzY3JpYmluZyBpbnRlZ3JhdGluZyB0aW1pbmcgZnVuY3Rpb25zIGZvciB0ZW1wbyBjYWxjdWxhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrU2lnbmFsIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1NpZ25hbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3BhcmFtID0gbmV3IFRpY2tQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBtdWx0aXBsaWVyOiBvcHRpb25zLm11bHRpcGxpZXIsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0aWNrc1RvVGltZSh0aWNrcywgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udGlja3NUb1RpbWUodGlja3MsIHdoZW4pO1xuICAgIH1cbiAgICB0aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udGltZVRvVGlja3MoZHVyYXRpb24sIHdoZW4pO1xuICAgIH1cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2spIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFRpbWVPZlRpY2sodGljayk7XG4gICAgfVxuICAgIGdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKTtcbiAgICB9XG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgbXVsdGlwbGllciBvbiB0aGUgYnBtIHZhbHVlLiBVc2VmdWwgZm9yIHNldHRpbmcgYSBQUFEgcmVsYXRpdmUgdG8gdGhlIGJhc2UgZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBtdWx0aXBsaWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubXVsdGlwbGllcjtcbiAgICB9XG4gICAgc2V0IG11bHRpcGxpZXIobSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5tdWx0aXBsaWVyID0gbTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJhbS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tTaWduYWwuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVGlja1NpZ25hbCB9IGZyb20gXCIuL1RpY2tTaWduYWxcIjtcbmltcG9ydCB7IEVRIH0gZnJvbSBcIi4uL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBVc2VzIFtUaWNrU2lnbmFsXShUaWNrU2lnbmFsKSB0byB0cmFjayBlbGFwc2VkIHRpY2tzIHdpdGggY29tcGxleCBhdXRvbWF0aW9uIGN1cnZlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tTb3VyY2UgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1NvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0YXRlIHRpbWVsaW5lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2Zmc2V0IHZhbHVlcyBvZiB0aGUgdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBUaWNrU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCBzdGF0ZVxuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgMCk7XG4gICAgICAgIC8vIGFkZCB0aGUgZmlyc3QgZXZlbnRcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSgwLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICB9LCBUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFN0YXRlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgY2xvY2sgYXQgdGhlIGdpdmVuIHRpbWUuIE9wdGlvbmFsbHkgcGFzcyBpbiBhbiBvZmZzZXRcbiAgICAgKiBvZiB3aGVyZSB0byBzdGFydCB0aGUgdGljayBjb3VudGVyIGZyb20uXG4gICAgICogQHBhcmFtICB0aW1lICAgIFRoZSB0aW1lIHRoZSBjbG9jayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBudW1iZXIgb2YgdGlja3MgdG8gc3RhcnQgdGhlIHNvdXJjZSBhdFxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmIChpc0RlZmluZWQob2Zmc2V0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUob2Zmc2V0LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGV2ZW50ICYmIGV2ZW50LnRpbWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGlja09mZnNldC5jYW5jZWwoZXZlbnQudGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSgwLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIGNsb2NrLiBQYXVzaW5nIGRvZXMgbm90IHJlc2V0IHRoZSB0aWNrIGNvdW50ZXIuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInBhdXNlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgc3RhcnQvc3RvcC9wYXVzZSBhbmQgc2V0VGlja0F0VGltZSBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdG8gY2xlYXIgdGhlIGV2ZW50cyBhZnRlclxuICAgICAqL1xuICAgIGNhbmNlbCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZWxhcHNlZCB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3NcbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRMYXN0U3RhdGUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIC8vIHRoaXMgZXZlbnQgYWxsb3dzIGZvckVhY2hCZXR3ZWVuIHRvIGl0ZXJhdGUgdW50aWwgdGhlIGN1cnJlbnQgdGltZVxuICAgICAgICBjb25zdCB0bXBFdmVudCA9IHsgc3RhdGU6IFwicGF1c2VkXCIsIHRpbWU6IGNvbXB1dGVkVGltZSB9O1xuICAgICAgICB0aGlzLl9zdGF0ZS5hZGQodG1wRXZlbnQpO1xuICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHRoZSBwcmV2aW91cyBvZmZzZXQgZXZlbnRcbiAgICAgICAgbGV0IGxhc3RTdGF0ZSA9IHN0b3BFdmVudDtcbiAgICAgICAgbGV0IGVsYXBzZWRUaWNrcyA9IDA7XG4gICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0b3BFdmVudC50aW1lLCBjb21wdXRlZFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUsIGUgPT4ge1xuICAgICAgICAgICAgbGV0IHBlcmlvZFN0YXJ0VGltZSA9IGxhc3RTdGF0ZS50aW1lO1xuICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gb2Zmc2V0IGV2ZW50IGluIHRoaXMgcGVyaW9kIHVzZSB0aGF0XG4gICAgICAgICAgICBjb25zdCBvZmZzZXRFdmVudCA9IHRoaXMuX3RpY2tPZmZzZXQuZ2V0KGUudGltZSk7XG4gICAgICAgICAgICBpZiAob2Zmc2V0RXZlbnQgJiYgb2Zmc2V0RXZlbnQudGltZSA+PSBsYXN0U3RhdGUudGltZSkge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRUaWNrcyA9IG9mZnNldEV2ZW50LnRpY2tzO1xuICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0VGltZSA9IG9mZnNldEV2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFzdFN0YXRlLnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBlLnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRUaWNrcyArPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShlLnRpbWUpIC0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUocGVyaW9kU3RhcnRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHRlbXBvcmFyeSBldmVudFxuICAgICAgICB0aGlzLl9zdGF0ZS5yZW1vdmUodG1wRXZlbnQpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIHRpY2tzXG4gICAgICAgIHJldHVybiBlbGFwc2VkVGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBTdGFydHMgY291bnRpbmcgYXQgMFxuICAgICAqIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gUmV0dXJucyAtMSB3aGVuIHN0b3BwZWQuXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaWNrc0F0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgc2V0IHRpY2tzKHQpIHtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSh0LCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2luY2UgdGlja3M9MCB0aGF0IHRoZSBUaWNrU291cmNlIGhhcyBiZWVuIHJ1bm5pbmcuIEFjY291bnRzXG4gICAgICogZm9yIHRlbXBvIGN1cnZlc1xuICAgICAqL1xuICAgIGdldCBzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTZWNvbmRzQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgc2Vjb25kcyhzKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5mcmVxdWVuY3kudGltZVRvVGlja3Mocywgbm93KTtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSh0aWNrcywgbm93KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRMYXN0U3RhdGUoXCJzdG9wcGVkXCIsIHRpbWUpO1xuICAgICAgICAvLyB0aGlzIGV2ZW50IGFsbG93cyBmb3JFYWNoQmV0d2VlbiB0byBpdGVyYXRlIHVudGlsIHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgY29uc3QgdG1wRXZlbnQgPSB7IHN0YXRlOiBcInBhdXNlZFwiLCB0aW1lIH07XG4gICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG4gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuICAgICAgICBsZXQgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuICAgICAgICBsZXQgZWxhcHNlZFNlY29uZHMgPSAwO1xuICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWxsIHRoZSBldmVudHMgc2luY2UgdGhlIGxhc3Qgc3RvcFxuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdG9wRXZlbnQudGltZSwgdGltZSArIHRoaXMuc2FtcGxlVGltZSwgZSA9PiB7XG4gICAgICAgICAgICBsZXQgcGVyaW9kU3RhcnRUaW1lID0gbGFzdFN0YXRlLnRpbWU7XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRFdmVudCAmJiBvZmZzZXRFdmVudC50aW1lID49IGxhc3RTdGF0ZS50aW1lKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgPSBvZmZzZXRFdmVudC5zZWNvbmRzO1xuICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0VGltZSA9IG9mZnNldEV2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFzdFN0YXRlLnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBlLnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRTZWNvbmRzICs9IGUudGltZSAtIHBlcmlvZFN0YXJ0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHRlbXBvcmFyeSBldmVudFxuICAgICAgICB0aGlzLl9zdGF0ZS5yZW1vdmUodG1wRXZlbnQpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIHRpY2tzXG4gICAgICAgIHJldHVybiBlbGFwc2VkU2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIHRpY2sgdmFsdWUgdG8gc2V0XG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHNldCB0aGUgdGljayB2YWx1ZVxuICAgICAqL1xuICAgIHNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5jYW5jZWwodGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuYWRkKHtcbiAgICAgICAgICAgIHNlY29uZHM6IHRoaXMuZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSksXG4gICAgICAgICAgICB0aWNrcyxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0U3RhdGVBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBnaXZlbiB0aWNrLiBUaGUgc2Vjb25kIGFyZ3VtZW50XG4gICAgICogaXMgd2hlbiB0byB0ZXN0IGJlZm9yZS4gU2luY2UgdGlja3MgY2FuIGJlIHNldCAod2l0aCBzZXRUaWNrc0F0VGltZSlcbiAgICAgKiB0aGVyZSBtYXkgYmUgbXVsdGlwbGUgdGltZXMgZm9yIGEgZ2l2ZW4gdGljayB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gIHRpY2sgVGhlIHRpY2sgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgYmVmb3JlIFdoZW4gdG8gbWVhc3VyZSB0aGUgdGljayB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgb2YgdGhlIHRpY2tcbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSA9IHRoaXMubm93KCkpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5fdGlja09mZnNldC5nZXQoYmVmb3JlKTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoYmVmb3JlKTtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gTWF0aC5tYXgob2Zmc2V0LnRpbWUsIGV2ZW50LnRpbWUpO1xuICAgICAgICBjb25zdCBhYnNvbHV0ZVRpY2tzID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUoc3RhcnRUaW1lKSArIHRpY2sgLSBvZmZzZXQudGlja3M7XG4gICAgICAgIHJldHVybiB0aGlzLmZyZXF1ZW5jeS5nZXRUaW1lT2ZUaWNrKGFic29sdXRlVGlja3MpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrIGV2ZW50IGF0IGFsbCBzY2hlZHVsZWQgdGlja3MgYmV0d2VlbiB0aGVcbiAgICAgKiBzdGFydCB0aW1lIGFuZCB0aGUgZW5kIHRpbWVcbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSAgVGhlIGJlZ2lubmluZyBvZiB0aGUgc2VhcmNoIHJhbmdlXG4gICAgICogQHBhcmFtICBlbmRUaW1lICAgIFRoZSBlbmQgb2YgdGhlIHNlYXJjaCByYW5nZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZWFjaCB0aWNrXG4gICAgICovXG4gICAgZm9yRWFjaFRpY2tCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gb25seSBpdGVyYXRlIHRocm91Z2ggdGhlIHNlY3Rpb25zIHdoZXJlIGl0IGlzIFwic3RhcnRlZFwiXG4gICAgICAgIGxldCBsYXN0U3RhdGVFdmVudCA9IHRoaXMuX3N0YXRlLmdldChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGVFdmVudCAmJiBsYXN0U3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiYgZXZlbnQuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JFYWNoVGlja0JldHdlZW4oTWF0aC5tYXgobGFzdFN0YXRlRXZlbnQudGltZSwgc3RhcnRUaW1lKSwgZXZlbnQudGltZSAtIHRoaXMuc2FtcGxlVGltZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlRXZlbnQgPSBldmVudDtcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBlcnJvciA9IG51bGw7XG4gICAgICAgIGlmIChsYXN0U3RhdGVFdmVudCAmJiBsYXN0U3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heFN0YXJ0VGltZSA9IE1hdGgubWF4KGxhc3RTdGF0ZUV2ZW50LnRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAvLyBmaWd1cmUgb3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGZyZXF1ZW5jeSB0aWNrcyBhbmQgdGhlXG4gICAgICAgICAgICBjb25zdCBzdGFydFRpY2tzID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUobWF4U3RhcnRUaW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzQXRTdGFydCA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKGxhc3RTdGF0ZUV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgY29uc3QgZGlmZiA9IHN0YXJ0VGlja3MgLSB0aWNrc0F0U3RhcnQ7XG4gICAgICAgICAgICBsZXQgb2Zmc2V0ID0gTWF0aC5jZWlsKGRpZmYpIC0gZGlmZjtcbiAgICAgICAgICAgIC8vIGd1YXJkIGFnYWluc3QgZmxvYXRpbmcgcG9pbnQgaXNzdWVzXG4gICAgICAgICAgICBvZmZzZXQgPSBFUShvZmZzZXQsIDEpID8gMCA6IG9mZnNldDtcbiAgICAgICAgICAgIGxldCBuZXh0VGlja1RpbWUgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaW1lT2ZUaWNrKHN0YXJ0VGlja3MgKyBvZmZzZXQpO1xuICAgICAgICAgICAgd2hpbGUgKG5leHRUaWNrVGltZSA8IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXh0VGlja1RpbWUsIE1hdGgucm91bmQodGhpcy5nZXRUaWNrc0F0VGltZShuZXh0VGlja1RpbWUpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHRUaWNrVGltZSArPSB0aGlzLmZyZXF1ZW5jeS5nZXREdXJhdGlvbk9mVGlja3MoMSwgbmV4dFRpY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrU291cmNlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGlja1NvdXJjZSB9IGZyb20gXCIuL1RpY2tTb3VyY2VcIjtcbmltcG9ydCB7IGFzc2VydENvbnRleHRSdW5uaW5nIH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQSBzYW1wbGUgYWNjdXJhdGUgY2xvY2sgd2hpY2ggcHJvdmlkZXMgYSBjYWxsYmFjayBhdCB0aGUgZ2l2ZW4gcmF0ZS5cbiAqIFdoaWxlIHRoZSBjYWxsYmFjayBpcyBub3Qgc2FtcGxlLWFjY3VyYXRlIChpdCBpcyBzdGlsbCBzdXNjZXB0aWJsZSB0b1xuICogbG9vc2UgSlMgdGltaW5nKSwgdGhlIHRpbWUgcGFzc2VkIGluIGFzIHRoZSBhcmd1bWVudCB0byB0aGUgY2FsbGJhY2tcbiAqIGlzIHByZWNpc2UuIEZvciBtb3N0IGFwcGxpY2F0aW9ucywgaXQgaXMgYmV0dGVyIHRvIHVzZSBUb25lLlRyYW5zcG9ydFxuICogaW5zdGVhZCBvZiB0aGUgQ2xvY2sgYnkgaXRzZWxmIHNpbmNlIHlvdSBjYW4gc3luY2hyb25pemUgbXVsdGlwbGUgY2FsbGJhY2tzLlxuICogQGV4YW1wbGVcbiAqIC8vIHRoZSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWQgYXBwcm94aW1hdGVseSBvbmNlIGEgc2Vjb25kXG4gKiAvLyBhbmQgd2lsbCBwcmludCB0aGUgdGltZSBleGFjdGx5IG9uY2UgYSBzZWNvbmQgYXBhcnQuXG4gKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKHRpbWUgPT4ge1xuICogXHRjb25zb2xlLmxvZyh0aW1lKTtcbiAqIH0sIDEpO1xuICogY2xvY2suc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG9jayBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENsb2NrLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDbG9ja1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGludm9rZSBhdCB0aGUgc2NoZWR1bGVkIHRpY2suXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gbm9PcDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsYXN0IHRpbWUgdGhlIGxvb3AgY2FsbGJhY2sgd2FzIGludm9rZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgcGxheWJhY2sgc3RhdGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udGV4dCBib3VuZCByZWZlcmVuY2UgdG8gdGhlIF9sb29wIG1ldGhvZFxuICAgICAgICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSB0byByZW1vdmUgdGhlIGV2ZW50IGluIHRoZSBlbmQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZExvb3AgPSB0aGlzLl9sb29wLmJpbmQodGhpcyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDbG9jay5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UgPSBuZXcgVGlja1NvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sYXN0VXBkYXRlID0gMDtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl90aWNrU291cmNlLmZyZXF1ZW5jeTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIC8vIGFkZCBhbiBpbml0aWFsIHN0YXRlXG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCAwKTtcbiAgICAgICAgLy8gYmluZCBhIGNhbGxiYWNrIHRvIHRoZSB3b3JrZXIgdGhyZWFkXG4gICAgICAgIHRoaXMuY29udGV4dC5vbihcInRpY2tcIiwgdGhpcy5fYm91bmRMb29wKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgY2xvY2sgYXQgdGhlIGdpdmVuIHRpbWUuIE9wdGlvbmFsbHkgcGFzcyBpbiBhbiBvZmZzZXRcbiAgICAgKiBvZiB3aGVyZSB0byBzdGFydCB0aGUgdGljayBjb3VudGVyIGZyb20uXG4gICAgICogQHBhcmFtICB0aW1lICAgIFRoZSB0aW1lIHRoZSBjbG9jayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gb2Zmc2V0ICBXaGVyZSB0aGUgdGljayBjb3VudGVyIHN0YXJ0cyBjb3VudGluZyBmcm9tLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGNvbnRleHQgaXMgcnVubmluZ1xuICAgICAgICBhc3NlcnRDb250ZXh0UnVubmluZyh0aGlzLmNvbnRleHQpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbG9vcFxuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zdGFydChjb21wdXRlZFRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgY2xvY2suIFN0b3BwaW5nIHRoZSBjbG9jayByZXNldHMgdGhlIHRpY2sgY291bnRlciB0byAwLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jayh0aW1lID0+IHtcbiAgICAgKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICAgICAqIH0sIDEpO1xuICAgICAqIGNsb2NrLnN0YXJ0KCk7XG4gICAgICogLy8gc3RvcCB0aGUgY2xvY2sgYWZ0ZXIgMTAgc2Vjb25kc1xuICAgICAqIGNsb2NrLnN0b3AoXCIrMTBcIik7XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKGNvbXB1dGVkVGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIGNsb2NrLiBQYXVzaW5nIGRvZXMgbm90IHJlc2V0IHRoZSB0aWNrIGNvdW50ZXIuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInBhdXNlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5wYXVzZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGNvbXB1dGVkVGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gU3RhcnRzIGNvdW50aW5nIGF0IDBcbiAgICAgKiBhbmQgaW5jcmVtZW50cyBhZnRlciB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMuZ2V0VGlja3NBdFRpbWUodGhpcy5ub3coKSkpO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnRpY2tzID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2luY2UgdGlja3M9MCB0aGF0IHRoZSBDbG9jayBoYXMgYmVlbiBydW5uaW5nLiBBY2NvdW50cyBmb3IgdGVtcG8gY3VydmVzXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLnNlY29uZHM7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZWNvbmRzID0gcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0U2Vjb25kc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIHRpY2sgdmFsdWUgdG8gc2V0XG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHNldCB0aGUgdGljayB2YWx1ZVxuICAgICAqL1xuICAgIHNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBnaXZlbiB0aWNrLiBUaGUgc2Vjb25kIGFyZ3VtZW50XG4gICAgICogaXMgd2hlbiB0byB0ZXN0IGJlZm9yZS4gU2luY2UgdGlja3MgY2FuIGJlIHNldCAod2l0aCBzZXRUaWNrc0F0VGltZSlcbiAgICAgKiB0aGVyZSBtYXkgYmUgbXVsdGlwbGUgdGltZXMgZm9yIGEgZ2l2ZW4gdGljayB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gIHRpY2sgVGhlIHRpY2sgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgYmVmb3JlIFdoZW4gdG8gbWVhc3VyZSB0aGUgdGljayB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgb2YgdGhlIHRpY2tcbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSA9IHRoaXMubm93KCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayh0aWNrLCBiZWZvcmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIHRpY2sgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBuZXh0IHRpY2tcbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgdGljayBudW1iZXIuXG4gICAgICovXG4gICAgbmV4dFRpY2tUaW1lKG9mZnNldCwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpbWVPZlRpY2soY3VycmVudFRpY2sgKyBvZmZzZXQsIGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzY2hlZHVsaW5nIGxvb3AuXG4gICAgICovXG4gICAgX2xvb3AoKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IHRoaXMuX2xhc3RVcGRhdGU7XG4gICAgICAgIGNvbnN0IGVuZFRpbWUgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl9sYXN0VXBkYXRlID0gZW5kVGltZTtcbiAgICAgICAgdGhpcy5sb2coXCJsb29wXCIsIHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgICAgIGlmIChzdGFydFRpbWUgIT09IGVuZFRpbWUpIHtcbiAgICAgICAgICAgIC8vIHRoZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGUgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZS5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3RhcnRlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5fdGlja1NvdXJjZS5nZXRUaWNrc0F0VGltZShlLnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgZS50aW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdG9wcGVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50aW1lICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCBlLnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwYXVzZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHRoZSB0aWNrIGNhbGxiYWNrc1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5mb3JFYWNoVGlja0JldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCAodGltZSwgdGlja3MpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRpY2tzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNjaGVkdWxlZCBzdGF0ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm4gIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSBpbnB1dCBpbiBzZXRTdGF0ZUF0VGltZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2soKTtcbiAgICAgKiBjbG9jay5zdGFydChcIiswLjFcIik7XG4gICAgICogY2xvY2suZ2V0U3RhdGVBdFRpbWUoXCIrMC4xXCIpOyAvLyByZXR1cm5zIFwic3RhcnRlZFwiXG4gICAgICovXG4gICAgZ2V0U3RhdGVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbnRleHQub2ZmKFwidGlja1wiLCB0aGlzLl9ib3VuZExvb3ApO1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5FbWl0dGVyLm1peGluKENsb2NrKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNsb2NrLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCBXZWIgQXVkaW8ncyBuYXRpdmUgW0RlbGF5Tm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtZGVsYXlub2RlLWludGVyZmFjZSkuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBkZWxheSA9IG5ldyBUb25lLkRlbGF5KDAuMSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBjb25uZWN0IHRoZSBzaWduYWwgdG8gYm90aCB0aGUgZGVsYXkgYW5kIHRoZSBkZXN0aW5hdGlvblxuICogXHRjb25zdCBwdWxzZSA9IG5ldyBUb25lLlB1bHNlT3NjaWxsYXRvcigpLmNvbm5lY3QoZGVsYXkpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Ly8gc3RhcnQgYW5kIHN0b3AgdGhlIHB1bHNlXG4gKiBcdHB1bHNlLnN0YXJ0KDApLnN0b3AoMC4wMSk7XG4gKiB9LCAwLjUsIDEpO1xuICovXG5leHBvcnQgY2xhc3MgRGVsYXkgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJtYXhEZWxheVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcIm1heERlbGF5XCJdKTtcbiAgICAgICAgY29uc3QgbWF4RGVsYXlJblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLm1heERlbGF5KTtcbiAgICAgICAgdGhpcy5fbWF4RGVsYXkgPSBNYXRoLm1heChtYXhEZWxheUluU2Vjb25kcywgdGhpcy50b1NlY29uZHMob3B0aW9ucy5kZWxheVRpbWUpKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZURlbGF5KG1heERlbGF5SW5TZWNvbmRzKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2RlbGF5Tm9kZS5kZWxheVRpbWUsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAsXG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIGRlbGF5IHRpbWUuIFRoaXMgY2Fubm90IGJlIGNoYW5nZWQgYWZ0ZXJcbiAgICAgKiB0aGUgdmFsdWUgaXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqL1xuICAgIGdldCBtYXhEZWxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heERlbGF5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVsYXkuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0LCBzZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4vVG9uZUF1ZGlvQnVmZmVyXCI7XG4vKipcbiAqIEdlbmVyYXRlIGEgYnVmZmVyIGJ5IHJlbmRlcmluZyBhbGwgb2YgdGhlIFRvbmUuanMgY29kZSB3aXRoaW4gdGhlIGNhbGxiYWNrIHVzaW5nIHRoZSBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICogVGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgaXMgY2FwYWJsZSBvZiByZW5kZXJpbmcgbXVjaCBmYXN0ZXIgdGhhbiByZWFsIHRpbWUgaW4gbWFueSBjYXNlcy5cbiAqIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBhbHNvIHBhc3NlcyBpbiBhbiBvZmZsaW5lIGluc3RhbmNlIG9mIFtbQ29udGV4dF1dIHdoaWNoIGNhbiBiZSB1c2VkXG4gKiB0byBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydC5cbiAqIEBwYXJhbSAgY2FsbGJhY2sgIEFsbCBUb25lLmpzIG5vZGVzIHdoaWNoIGFyZSBjcmVhdGVkIGFuZCBzY2hlZHVsZWQgd2l0aGluIHRoaXMgY2FsbGJhY2sgYXJlIHJlY29yZGVkIGludG8gdGhlIG91dHB1dCBCdWZmZXIuXG4gKiBAcGFyYW0gIGR1cmF0aW9uICAgICB0aGUgYW1vdW50IG9mIHRpbWUgdG8gcmVjb3JkIGZvci5cbiAqIEByZXR1cm4gIFRoZSBwcm9taXNlIHdoaWNoIGlzIGludm9rZWQgd2l0aCB0aGUgVG9uZUF1ZGlvQnVmZmVyIG9mIHRoZSByZWNvcmRlZCBvdXRwdXQuXG4gKiBAZXhhbXBsZVxuICogLy8gcmVuZGVyIDIgc2Vjb25kcyBvZiB0aGUgb3NjaWxsYXRvclxuICogVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Ly8gb25seSBub2RlcyBjcmVhdGVkIGluIHRoaXMgY2FsbGJhY2sgd2lsbCBiZSByZWNvcmRlZFxuICogXHRjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgwKTtcbiAqIH0sIDIpLnRoZW4oKGJ1ZmZlcikgPT4ge1xuICogXHQvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgb3V0cHV0IGJ1ZmZlclxuICogXHRjb25zb2xlLmxvZyhidWZmZXIpO1xuICogfSk7XG4gKiBAZXhhbXBsZVxuICogLy8gY2FuIGFsc28gc2NoZWR1bGUgZXZlbnRzIGFsb25nIHRoZSBUcmFuc3BvcnRcbiAqIC8vIHVzaW5nIHRoZSBwYXNzZWQgaW4gT2ZmbGluZSBUcmFuc3BvcnRcbiAqIFRvbmUuT2ZmbGluZSgoeyB0cmFuc3BvcnQgfSkgPT4ge1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHR0cmFuc3BvcnQuc2NoZWR1bGUodGltZSA9PiB7XG4gKiBcdFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gKiBcdH0sIDEpO1xuICogXHQvLyBtYWtlIHN1cmUgdG8gc3RhcnQgdGhlIHRyYW5zcG9ydFxuICogXHR0cmFuc3BvcnQuc3RhcnQoMC4yKTtcbiAqIH0sIDQpLnRoZW4oKGJ1ZmZlcikgPT4ge1xuICogXHQvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgb3V0cHV0IGJ1ZmZlclxuICogXHRjb25zb2xlLmxvZyhidWZmZXIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gT2ZmbGluZShjYWxsYmFjaywgZHVyYXRpb24sIGNoYW5uZWxzID0gMiwgc2FtcGxlUmF0ZSA9IGdldENvbnRleHQoKS5zYW1wbGVSYXRlKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgLy8gc2V0IHRoZSBPZmZsaW5lQXVkaW9Db250ZXh0IGJhc2VkIG9uIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxDb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KGNoYW5uZWxzLCBkdXJhdGlvbiwgc2FtcGxlUmF0ZSk7XG4gICAgICAgIHNldENvbnRleHQoY29udGV4dCk7XG4gICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2svc2NoZWR1bGluZ1xuICAgICAgICB5aWVsZCBjYWxsYmFjayhjb250ZXh0KTtcbiAgICAgICAgLy8gdGhlbiByZW5kZXIgdGhlIGF1ZGlvXG4gICAgICAgIGNvbnN0IGJ1ZmZlclByb21pc2UgPSBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIG9yaWdpbmFsIEF1ZGlvQ29udGV4dFxuICAgICAgICBzZXRDb250ZXh0KG9yaWdpbmFsQ29udGV4dCk7XG4gICAgICAgIC8vIGF3YWl0IHRoZSByZW5kZXJpbmdcbiAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgYnVmZmVyUHJvbWlzZTtcbiAgICAgICAgLy8gcmV0dXJuIHRoZSBhdWRpb1xuICAgICAgICByZXR1cm4gbmV3IFRvbmVBdWRpb0J1ZmZlcihidWZmZXIpO1xuICAgIH0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T2ZmbGluZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEEgZGF0YSBzdHJ1Y3R1cmUgZm9yIGhvbGRpbmcgbXVsdGlwbGUgYnVmZmVycyBpbiBhIE1hcC1saWtlIGRhdGFzdHJ1Y3R1cmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBpYW5vU2FtcGxlcyA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcnMoe1xuICogXHRBMTogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vQTEubXAzXCIsXG4gKiBcdEEyOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMi5tcDNcIixcbiAqIH0sICgpID0+IHtcbiAqIFx0Y29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBwbGF5IG9uZSBvZiB0aGUgc2FtcGxlcyB3aGVuIHRoZXkgYWxsIGxvYWRcbiAqIFx0cGxheWVyLmJ1ZmZlciA9IHBpYW5vU2FtcGxlcy5nZXQoXCJBMlwiKTtcbiAqIFx0cGxheWVyLnN0YXJ0KCk7XG4gKiB9KTtcbiAqIEBleGFtcGxlXG4gKiAvLyBUbyBwYXNzIGluIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBpbiB0aGUgc2Vjb25kIHBhcmFtZXRlclxuICogY29uc3QgYnVmZmVycyA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcnMoe1xuICogXHQgdXJsczoge1xuICogXHRcdCBBMTogXCJBMS5tcDNcIixcbiAqIFx0XHQgQTI6IFwiQTIubXAzXCIsXG4gKiBcdCB9LFxuICogXHQgb25sb2FkOiAoKSA9PiBjb25zb2xlLmxvZyhcImxvYWRlZFwiKSxcbiAqIFx0IGJhc2VVcmw6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL1wiXG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9CdWZmZXJzIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvQnVmZmVyc1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBidWZmZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIGxvYWRlZCBidWZmZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUF1ZGlvQnVmZmVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIik7XG4gICAgICAgIHRoaXMuYmFzZVVybCA9IG9wdGlvbnMuYmFzZVVybDtcbiAgICAgICAgLy8gYWRkIGVhY2ggb25lXG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMudXJscykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCsrO1xuICAgICAgICAgICAgY29uc3QgdXJsID0gb3B0aW9ucy51cmxzW25hbWVdO1xuICAgICAgICAgICAgdGhpcy5hZGQobmFtZSwgdXJsLCB0aGlzLl9idWZmZXJMb2FkZWQuYmluZCh0aGlzLCBvcHRpb25zLm9ubG9hZCksIG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBiYXNlVXJsOiBcIlwiLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcnVlIGlmIHRoZSBidWZmZXJzIG9iamVjdCBoYXMgYSBidWZmZXIgYnkgdGhhdCBuYW1lLlxuICAgICAqIEBwYXJhbSAgbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhcyhuYW1lLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBidWZmZXIgYnkgbmFtZS4gSWYgYW4gYXJyYXkgd2FzIGxvYWRlZCxcbiAgICAgKiB0aGVuIHVzZSB0aGUgYXJyYXkgaW5kZXguXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgZ2V0KG5hbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuaGFzKG5hbWUpLCBgVG9uZUF1ZGlvQnVmZmVycyBoYXMgbm8gYnVmZmVyIG5hbWVkOiAke25hbWV9YCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmdldChuYW1lLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGJ1ZmZlciB3YXMgbG9hZGVkLiBkZWNyZW1lbnQgdGhlIGNvdW50ZXIuXG4gICAgICovXG4gICAgX2J1ZmZlckxvYWRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQtLTtcbiAgICAgICAgaWYgKHRoaXMuX2xvYWRpbmdDb3VudCA9PT0gMCAmJiBjYWxsYmFjaykge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2J1ZmZlcnMpLmV2ZXJ5KChbXywgYnVmZmVyXSkgPT4gYnVmZmVyLmxvYWRlZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIGJ1ZmZlciBieSBuYW1lIGFuZCB1cmwgdG8gdGhlIEJ1ZmZlcnNcbiAgICAgKiBAcGFyYW0gIG5hbWUgICAgICBBIHVuaXF1ZSBuYW1lIHRvIGdpdmUgdGhlIGJ1ZmZlclxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIsIG9yIGEgYnVmZmVyIHdoaWNoIHdpbGwgYmUgYWRkZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIHVybCBpcyBsb2FkZWQuXG4gICAgICogQHBhcmFtICBvbmVycm9yICBJbnZva2VkIGlmIHRoZSBidWZmZXIgY2FuJ3QgYmUgbG9hZGVkXG4gICAgICovXG4gICAgYWRkKG5hbWUsIHVybCwgY2FsbGJhY2sgPSBub09wLCBvbmVycm9yID0gbm9PcCkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodXJsKSkge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5zZXQobmFtZS50b1N0cmluZygpLCBuZXcgVG9uZUF1ZGlvQnVmZmVyKHRoaXMuYmFzZVVybCArIHVybCwgY2FsbGJhY2ssIG9uZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuc2V0KG5hbWUudG9TdHJpbmcoKSwgbmV3IFRvbmVBdWRpb0J1ZmZlcih1cmwsIGNhbGxiYWNrLCBvbmVycm9yKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5mb3JFYWNoKGJ1ZmZlciA9PiBidWZmZXIuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9CdWZmZXJzLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBmdG9tLCBtdG9mIH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4vRnJlcXVlbmN5XCI7XG4vKipcbiAqIE1pZGkgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBNaWRpIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIE1pZGkgY2FuIGJlIHBhc3NlZFxuICogaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRpQ2xhc3MgZXh0ZW5kcyBGcmVxdWVuY3lDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkaUNsYXNzXCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJtaWRpXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fdGlja3NUb1VuaXRzKHRpY2tzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fYmVhdHNUb1VuaXRzKGJlYXRzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oc3VwZXIuX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLk1pZGkoNjApLnRvTWlkaSgpOyAvLyA2MFxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaSg2MCkudG9GcmVxdWVuY3koKTsgLy8gMjYxLjYyNTU2NTMwMDU5ODZcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIG10b2YodGhpcy50b01pZGkoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cbiAgICAgKiBAcmV0dXJuIEEgbmV3IHRyYW5zcG9zZWQgTWlkaUNsYXNzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLk1pZGkoXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vIFwiQzVcIlxuICAgICAqL1xuICAgIHRyYW5zcG9zZShpbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gbmV3IE1pZGlDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMudG9NaWRpKCkgKyBpbnRlcnZhbCk7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgaW50byBhIEZyZXF1ZW5jeUNsYXNzIG9iamVjdC5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBNaWRpKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgTWlkaUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZGkuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuL1RyYW5zcG9ydFRpbWVcIjtcbi8qKlxuICogVGlja3MgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBUaWNrcyBjYW4gYmUgY29uc3RydWN0ZWQgd2l0aCBvciB3aXRob3V0IHRoZSBgbmV3YCBrZXl3b3JkLiBUaWNrcyBjYW4gYmUgcGFzc2VkXG4gKiBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHQgPSBUb25lLlRpY2tzKFwiNG5cIik7IC8vIGEgcXVhcnRlciBub3RlIGFzIHRpY2tzXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgVGlja3NDbGFzcyBleHRlbmRzIFRyYW5zcG9ydFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja3NcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcImlcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHRpbWUgaW4gdGhlIGdpdmVuIHVuaXRzXG4gICAgICovXG4gICAgX25vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQudGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UFBRKCkgKiBiZWF0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihzZWNvbmRzIC8gKDYwIC8gdGhpcy5fZ2V0QnBtKCkpICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuIHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gdGlja3NcbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBzZWNvbmRzXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMudmFsdWVPZigpIC8gdGhpcy5fZ2V0UFBRKCkpICogKDYwIC8gdGhpcy5fZ2V0QnBtKCkpO1xuICAgIH1cbn1cbi8qKlxuICogQ29udmVydCBhIHRpbWUgcmVwcmVzZW50YXRpb24gdG8gdGlja3NcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUaWNrcyh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja3MuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuLyoqXG4gKiBEcmF3IGlzIHVzZWZ1bCBmb3Igc3luY2hyb25pemluZyB2aXN1YWxzIGFuZCBhdWRpbyBldmVudHMuXG4gKiBDYWxsYmFja3MgZnJvbSBUb25lLlRyYW5zcG9ydCBvciBhbnkgb2YgdGhlIFRvbmUuRXZlbnQgY2xhc3Nlc1xuICogYWx3YXlzIGhhcHBlbiBfYmVmb3JlXyB0aGUgc2NoZWR1bGVkIHRpbWUgYW5kIGFyZSBub3Qgc3luY2hyb25pemVkXG4gKiB0byB0aGUgYW5pbWF0aW9uIGZyYW1lIHNvIHRoZXkgYXJlIG5vdCBnb29kIGZvciB0cmlnZ2VyaW5nIHRpZ2h0bHlcbiAqIHN5bmNocm9uaXplZCB2aXN1YWxzIGFuZCBzb3VuZC4gRHJhdyBtYWtlcyBpdCBlYXN5IHRvIHNjaGVkdWxlXG4gKiBjYWxsYmFja3MgdXNpbmcgdGhlIEF1ZGlvQ29udGV4dCB0aW1lIGFuZCB1c2VzIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cbiAqIEBleGFtcGxlXG4gKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZSgodGltZSkgPT4ge1xuICogXHQvLyB1c2UgdGhlIHRpbWUgYXJndW1lbnQgdG8gc2NoZWR1bGUgYSBjYWxsYmFjayB3aXRoIERyYXdcbiAqIFx0VG9uZS5EcmF3LnNjaGVkdWxlKCgpID0+IHtcbiAqIFx0XHQvLyBkbyBkcmF3aW5nIG9yIERPTSBtYW5pcHVsYXRpb24gaGVyZVxuICogXHRcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogXHR9LCB0aW1lKTtcbiAqIH0sIFwiKzAuNVwiKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRHJhdyBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRHJhd1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGR1cmF0aW9uIGFmdGVyIHdoaWNoIGV2ZW50cyBhcmUgbm90IGludm9rZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmV4cGlyYXRpb24gPSAwLjI1O1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGJlZm9yZSB0aGUgc2NoZWR1bGVkIHRpbWVcbiAgICAgICAgICogdGhhdCB0aGUgY2FsbGJhY2sgY2FuIGJlIGludm9rZWQuIERlZmF1bHQgaXNcbiAgICAgICAgICogaGFsZiB0aGUgdGltZSBvZiBhbiBhbmltYXRpb24gZnJhbWUgKDAuMDA4IHNlY29uZHMpLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hbnRpY2lwYXRpb24gPSAwLjAwODtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZHJhdyBsb29wXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZERyYXdMb29wID0gdGhpcy5fZHJhd0xvb3AuYmluZCh0aGlzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbmltYXRpb24gZnJhbWUgaWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbkZyYW1lID0gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGEgZnVuY3Rpb24gYXQgdGhlIGdpdmVuIHRpbWUgdG8gYmUgaW52b2tlZFxuICAgICAqIG9uIHRoZSBuZWFyZXN0IGFuaW1hdGlvbiBmcmFtZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBDYWxsYmFjayBpcyBpbnZva2VkIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgIFRoZSB0aW1lIHJlbGF0aXZlIHRvIHRoZSBBdWRpb0NvbnRleHQgdGltZSB0byBpbnZva2UgdGhlIGNhbGxiYWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGltZSA9PiB7XG4gICAgICogXHRUb25lLkRyYXcuc2NoZWR1bGUoKCkgPT4gY29uc29sZS5sb2codGltZSksIHRpbWUpO1xuICAgICAqIH0sIDEpO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICovXG4gICAgc2NoZWR1bGUoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIHRpbWU6IHRoaXMudG9TZWNvbmRzKHRpbWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIGRyYXcgbG9vcCBvbiB0aGUgZmlyc3QgZXZlbnRcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuX2JvdW5kRHJhd0xvb3ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZXZlbnRzIHNjaGVkdWxlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRpbWUgYWZ0ZXIgd2hpY2ggc2NoZWR1bGVkIGV2ZW50cyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgc2NoZWR1bGluZyB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbCh0aGlzLnRvU2Vjb25kcyhhZnRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRyYXcgbG9vcFxuICAgICAqL1xuICAgIF9kcmF3TG9vcCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICB3aGlsZSAodGhpcy5fZXZlbnRzLmxlbmd0aCAmJiB0aGlzLl9ldmVudHMucGVlaygpLnRpbWUgLSB0aGlzLmFudGljaXBhdGlvbiA8PSBub3cpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgbm93IC0gZXZlbnQudGltZSA8PSB0aGlzLmV4cGlyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBldmVudC5jYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZGlzcG9zZSgpO1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl9hbmltYXRpb25GcmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZHJhdyA9IG5ldyBEcmF3KHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kcmF3LmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHJhdy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogU2ltaWxhciB0byBUb25lLlRpbWVsaW5lLCBidXQgYWxsIGV2ZW50cyByZXByZXNlbnRcbiAqIGludGVydmFscyB3aXRoIGJvdGggXCJ0aW1lXCIgYW5kIFwiZHVyYXRpb25cIiB0aW1lcy4gVGhlXG4gKiBldmVudHMgYXJlIHBsYWNlZCBpbiBhIHRyZWUgc3RydWN0dXJlIG9wdGltaXplZFxuICogZm9yIHF1ZXJ5aW5nIGFuIGludGVyc2VjdGlvbiBwb2ludCB3aXRoIHRoZSB0aW1lbGluZVxuICogZXZlbnRzLiBJbnRlcm5hbGx5IHVzZXMgYW4gW0ludGVydmFsIFRyZWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ludGVydmFsX3RyZWUpXG4gKiB0byByZXByZXNlbnQgdGhlIGRhdGEuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnRlcnZhbFRpbWVsaW5lIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiSW50ZXJ2YWxUaW1lbGluZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaW50ZXZhbCB0cmVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIGxlbmd0aCBvZiB0aGUgdGltZWxpbmUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgdG8gYWRkIHRvIHRoZSB0aW1lbGluZS4gQWxsIGV2ZW50cyBtdXN0XG4gICAgICogaGF2ZSBhIHRpbWUgYW5kIGR1cmF0aW9uIHZhbHVlXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIGFkZCB0byB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICBhZGQoZXZlbnQpIHtcbiAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZChldmVudC50aW1lKSwgXCJFdmVudHMgbXVzdCBoYXZlIGEgdGltZSBwcm9wZXJ0eVwiKTtcbiAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZChldmVudC5kdXJhdGlvbiksIFwiRXZlbnRzIG11c3QgaGF2ZSBhIGR1cmF0aW9uIHBhcmFtZXRlclwiKTtcbiAgICAgICAgZXZlbnQudGltZSA9IGV2ZW50LnRpbWUudmFsdWVPZigpO1xuICAgICAgICBsZXQgbm9kZSA9IG5ldyBJbnRlcnZhbE5vZGUoZXZlbnQudGltZSwgZXZlbnQudGltZSArIGV2ZW50LmR1cmF0aW9uLCBldmVudCk7XG4gICAgICAgIGlmICh0aGlzLl9yb290ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QuaW5zZXJ0KG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xlbmd0aCsrO1xuICAgICAgICAvLyBSZXN0cnVjdHVyZSB0cmVlIHRvIGJlIGJhbGFuY2VkXG4gICAgICAgIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICAgICAgbm9kZS51cGRhdGVNYXgoKTtcbiAgICAgICAgICAgIHRoaXMuX3JlYmFsYW5jZShub2RlKTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBldmVudCB0byByZW1vdmUgZnJvbSB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICByZW1vdmUoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKGV2ZW50LnRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCA9PT0gZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlTm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgdGltZWxpbmUuXG4gICAgICogQHJlYWRPbmx5XG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGV2ZW50cyB3aG9zZSB0aW1lIHRpbWUgaXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIGFmdGVyICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5mb3JFYWNoRnJvbShhZnRlciwgZXZlbnQgPT4gdGhpcy5yZW1vdmUoZXZlbnQpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgcm9vdCBub2RlIGFzIHRoZSBnaXZlbiBub2RlXG4gICAgICovXG4gICAgX3NldFJvb3Qobm9kZSkge1xuICAgICAgICB0aGlzLl9yb290ID0gbm9kZTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QucGFyZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlIHRoZSByZWZlcmVuY2VzIHRvIHRoZSBub2RlIGluIHRoZSBub2RlJ3MgcGFyZW50XG4gICAgICogd2l0aCB0aGUgcmVwbGFjZW1lbnQgbm9kZS5cbiAgICAgKi9cbiAgICBfcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCByZXBsYWNlbWVudCkge1xuICAgICAgICBpZiAobm9kZS5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTGVmdENoaWxkKCkpIHtcbiAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKG5vZGUucGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgbm9kZSBmcm9tIHRoZSB0cmVlIGFuZCByZXBsYWNlIGl0IHdpdGhcbiAgICAgKiBhIHN1Y2Nlc3NvciB3aGljaCBmb2xsb3dzIHRoZSBzY2hlbWEuXG4gICAgICovXG4gICAgX3JlbW92ZU5vZGUobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sZWZ0ID09PSBudWxsICYmIG5vZGUucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBub2RlLmxlZnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5vZGUubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBub2RlLnJpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGJhbGFuY2UgPSBub2RlLmdldEJhbGFuY2UoKTtcbiAgICAgICAgICAgIGxldCByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIGxldCB0ZW1wID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChiYWxhbmNlID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxlZnQucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnQucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudC5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50LnBhcmVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LmxlZnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChub2RlLnJpZ2h0LmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUucmlnaHQubGVmdDtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVwbGFjZW1lbnQubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LmxlZnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50LnBhcmVudDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmlzTGVmdENoaWxkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRSb290KHJlcGxhY2VtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0ZW1wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKHRlbXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG5vZGUuZGlzcG9zZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhlIHRyZWUgdG8gdGhlIGxlZnRcbiAgICAgKi9cbiAgICBfcm90YXRlTGVmdChub2RlKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgICAgICBjb25zdCBpc0xlZnRDaGlsZCA9IG5vZGUuaXNMZWZ0Q2hpbGQoKTtcbiAgICAgICAgLy8gTWFrZSBub2RlLnJpZ2h0IHRoZSBuZXcgcm9vdCBvZiB0aGlzIHN1YiB0cmVlIChpbnN0ZWFkIG9mIG5vZGUpXG4gICAgICAgIGNvbnN0IHBpdm90Tm9kZSA9IG5vZGUucmlnaHQ7XG4gICAgICAgIGlmIChwaXZvdE5vZGUpIHtcbiAgICAgICAgICAgIG5vZGUucmlnaHQgPSBwaXZvdE5vZGUubGVmdDtcbiAgICAgICAgICAgIHBpdm90Tm9kZS5sZWZ0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhlIHRyZWUgdG8gdGhlIHJpZ2h0XG4gICAgICovXG4gICAgX3JvdGF0ZVJpZ2h0KG5vZGUpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGVmdENoaWxkID0gbm9kZS5pc0xlZnRDaGlsZCgpO1xuICAgICAgICAvLyBNYWtlIG5vZGUubGVmdCB0aGUgbmV3IHJvb3Qgb2YgdGhpcyBzdWIgdHJlZSAoaW5zdGVhZCBvZiBub2RlKVxuICAgICAgICBjb25zdCBwaXZvdE5vZGUgPSBub2RlLmxlZnQ7XG4gICAgICAgIGlmIChwaXZvdE5vZGUpIHtcbiAgICAgICAgICAgIG5vZGUubGVmdCA9IHBpdm90Tm9kZS5yaWdodDtcbiAgICAgICAgICAgIHBpdm90Tm9kZS5yaWdodCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGlzTGVmdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LmxlZnQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQucmlnaHQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRSb290KHBpdm90Tm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQmFsYW5jZSB0aGUgQlNUXG4gICAgICovXG4gICAgX3JlYmFsYW5jZShub2RlKSB7XG4gICAgICAgIGNvbnN0IGJhbGFuY2UgPSBub2RlLmdldEJhbGFuY2UoKTtcbiAgICAgICAgaWYgKGJhbGFuY2UgPiAxICYmIG5vZGUubGVmdCkge1xuICAgICAgICAgICAgaWYgKG5vZGUubGVmdC5nZXRCYWxhbmNlKCkgPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlLmxlZnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlUmlnaHQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmFsYW5jZSA8IC0xICYmIG5vZGUucmlnaHQpIHtcbiAgICAgICAgICAgIGlmIChub2RlLnJpZ2h0LmdldEJhbGFuY2UoKSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlLnJpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZUxlZnQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFuIGV2ZW50IHdob3NlIHRpbWUgYW5kIGR1cmF0aW9uIHNwYW4gdGhlIGdpdmUgdGltZS4gV2lsbFxuICAgICAqIHJldHVybiB0aGUgbWF0Y2ggd2hvc2UgXCJ0aW1lXCIgdmFsdWUgaXMgY2xvc2VzdCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcmV0dXJuICBUaGUgZXZlbnQgd2hpY2ggc3BhbnMgdGhlIGRlc2lyZWQgdGltZVxuICAgICAqL1xuICAgIGdldCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnNlYXJjaCh0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgbWF4ID0gcmVzdWx0c1swXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdHNbaV0ubG93ID4gbWF4Lmxvdykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4ID0gcmVzdWx0c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWF4LmV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbE5vZGVzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnRyYXZlcnNlKG5vZGUgPT4gYWxsTm9kZXMucHVzaChub2RlKSk7XG4gICAgICAgICAgICBhbGxOb2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUuZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBvdmVybGFwcyB3aXRoIHRoZSB0aW1lIGFuZCBkdXJhdGlvbiB0aW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIG92ZXJsYXBwaW5nXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBdFRpbWUodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgcmVzdWx0cy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUuZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIHRpbWUgaXMgZ3JlYXRlclxuICAgICAqIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEZyb20odGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoQWZ0ZXIodGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICByZXN1bHRzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC50cmF2ZXJzZShub2RlID0+IG5vZGUuZGlzcG9zZSgpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOVEVSVkFMIE5PREUgSEVMUEVSXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogUmVwcmVzZW50cyBhIG5vZGUgaW4gdGhlIGJpbmFyeSBzZWFyY2ggdHJlZSwgd2l0aCB0aGUgYWRkaXRpb25cbiAqIG9mIGEgXCJoaWdoXCIgdmFsdWUgd2hpY2gga2VlcHMgdHJhY2sgb2YgdGhlIGhpZ2hlc3QgdmFsdWUgb2ZcbiAqIGl0cyBjaGlsZHJlbi5cbiAqIFJlZmVyZW5jZXM6XG4gKiBodHRwczovL2Jyb29rbm92YWsud29yZHByZXNzLmNvbS8yMDEzLzEyLzA3L2F1Z21lbnRlZC1pbnRlcnZhbC10cmVlLWluLWMvXG4gKiBodHRwOi8vd3d3Lm1pZi52dS5sdC9+dmFsZGFzL0FMR09SSVRNQUkvTElURVJBVFVSQS9Db3JtZW4vQ29ybWVuLnBkZlxuICogQHBhcmFtIGxvd1xuICogQHBhcmFtIGhpZ2hcbiAqL1xuY2xhc3MgSW50ZXJ2YWxOb2RlIHtcbiAgICBjb25zdHJ1Y3Rvcihsb3csIGhpZ2gsIGV2ZW50KSB7XG4gICAgICAgIC8vIHRoZSBub2RlcyB0byB0aGUgbGVmdFxuICAgICAgICB0aGlzLl9sZWZ0ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIG5vZGVzIHRvIHRoZSByaWdodFxuICAgICAgICB0aGlzLl9yaWdodCA9IG51bGw7XG4gICAgICAgIC8vIHRoZSBwYXJlbnQgbm9kZVxuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIC8vIHRoZSBudW1iZXIgb2YgY2hpbGQgbm9kZXNcbiAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB0aGlzLmV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIC8vIHRoZSBsb3cgdmFsdWVcbiAgICAgICAgdGhpcy5sb3cgPSBsb3c7XG4gICAgICAgIC8vIHRoZSBoaWdoIHZhbHVlXG4gICAgICAgIHRoaXMuaGlnaCA9IGhpZ2g7XG4gICAgICAgIC8vIHRoZSBoaWdoIHZhbHVlIGZvciB0aGlzIGFuZCBhbGwgY2hpbGQgbm9kZXNcbiAgICAgICAgdGhpcy5tYXggPSB0aGlzLmhpZ2g7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc2VydCBhIG5vZGUgaW50byB0aGUgY29ycmVjdCBzcG90IGluIHRoZSB0cmVlXG4gICAgICovXG4gICAgaW5zZXJ0KG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUubG93IDw9IHRoaXMubG93KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0ID0gbm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdC5pbnNlcnQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0Lmluc2VydChub2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhlIHRyZWUgZm9yIG5vZGVzIHdoaWNoIG92ZXJsYXBcbiAgICAgKiB3aXRoIHRoZSBnaXZlbiBwb2ludFxuICAgICAqIEBwYXJhbSAgcG9pbnQgIFRoZSBwb2ludCB0byBxdWVyeVxuICAgICAqIEBwYXJhbSAgcmVzdWx0cyAgVGhlIGFycmF5IHRvIHB1dCB0aGUgcmVzdWx0c1xuICAgICAqL1xuICAgIHNlYXJjaChwb2ludCwgcmVzdWx0cykge1xuICAgICAgICAvLyBJZiBwIGlzIHRvIHRoZSByaWdodCBvZiB0aGUgcmlnaHRtb3N0IHBvaW50IG9mIGFueSBpbnRlcnZhbFxuICAgICAgICAvLyBpbiB0aGlzIG5vZGUgYW5kIGFsbCBjaGlsZHJlbiwgdGhlcmUgd29uJ3QgYmUgYW55IG1hdGNoZXMuXG4gICAgICAgIGlmIChwb2ludCA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VhcmNoIGxlZnQgY2hpbGRyZW5cbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sZWZ0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG4gICAgICAgIGlmICh0aGlzLmxvdyA8PSBwb2ludCAmJiB0aGlzLmhpZ2ggPiBwb2ludCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIGxlZnQgb2YgdGhlIHRpbWUgb2YgdGhpcyBpbnRlcnZhbCxcbiAgICAgICAgLy8gdGhlbiBpdCBjYW4ndCBiZSBpbiBhbnkgY2hpbGQgdG8gdGhlIHJpZ2h0LlxuICAgICAgICBpZiAodGhpcy5sb3cgPiBwb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlYXJjaCByaWdodCBjaGlsZHJlblxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC5zZWFyY2gocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgdHJlZSBmb3Igbm9kZXMgd2hpY2ggYXJlIGxlc3NcbiAgICAgKiB0aGFuIHRoZSBnaXZlbiBwb2ludFxuICAgICAqIEBwYXJhbSAgcG9pbnQgIFRoZSBwb2ludCB0byBxdWVyeVxuICAgICAqIEBwYXJhbSAgcmVzdWx0cyAgVGhlIGFycmF5IHRvIHB1dCB0aGUgcmVzdWx0c1xuICAgICAqL1xuICAgIHNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKSB7XG4gICAgICAgIC8vIENoZWNrIHRoaXMgbm9kZVxuICAgICAgICBpZiAodGhpcy5sb3cgPj0gcG9pbnQpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQuc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNlYXJjaCB0aGUgcmlnaHQgc2lkZVxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC5zZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBjYWxsYmFjayBvbiB0aGlzIGVsZW1lbnQgYW5kIGJvdGggaXQncyBicmFuY2hlc1xuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2tcbiAgICAgKi9cbiAgICB0cmF2ZXJzZShjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sZWZ0LnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC50cmF2ZXJzZShjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBoZWlnaHQgb2YgdGhlIG5vZGVcbiAgICAgKi9cbiAgICB1cGRhdGVIZWlnaHQoKSB7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwgJiYgdGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBNYXRoLm1heCh0aGlzLmxlZnQuaGVpZ2h0LCB0aGlzLnJpZ2h0LmhlaWdodCkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5yaWdodC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLmxlZnQuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuICAgICAqL1xuICAgIHVwZGF0ZU1heCgpIHtcbiAgICAgICAgdGhpcy5tYXggPSB0aGlzLmhpZ2g7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gTWF0aC5tYXgodGhpcy5tYXgsIHRoaXMubGVmdC5tYXgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1heCA9IE1hdGgubWF4KHRoaXMubWF4LCB0aGlzLnJpZ2h0Lm1heCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhbGFuY2UgaXMgaG93IHRoZSBsZWFmcyBhcmUgZGlzdHJpYnV0ZWQgb24gdGhlIG5vZGVcbiAgICAgKiBAcmV0dXJuICBOZWdhdGl2ZSBudW1iZXJzIGFyZSBiYWxhbmNlZCB0byB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBnZXRCYWxhbmNlKCkge1xuICAgICAgICBsZXQgYmFsYW5jZSA9IDA7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwgJiYgdGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgLSB0aGlzLnJpZ2h0LmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSB0aGlzLmxlZnQuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gLSh0aGlzLnJpZ2h0LmhlaWdodCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYWxhbmNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoaXMgbm9kZSBpcyB0aGUgbGVmdCBjaGlsZCBvZiBpdHMgcGFyZW50XG4gICAgICovXG4gICAgaXNMZWZ0Q2hpbGQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudCAhPT0gbnVsbCAmJiB0aGlzLnBhcmVudC5sZWZ0ID09PSB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQvc2V0IHRoZSBsZWZ0IG5vZGVcbiAgICAgKi9cbiAgICBnZXQgbGVmdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xlZnQ7XG4gICAgfVxuICAgIHNldCBsZWZ0KG5vZGUpIHtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG5vZGU7XG4gICAgICAgIGlmIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnBhcmVudCA9IHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgdGhpcy51cGRhdGVNYXgoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZ2V0L3NldCB0aGUgcmlnaHQgbm9kZVxuICAgICAqL1xuICAgIGdldCByaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JpZ2h0O1xuICAgIH1cbiAgICBzZXQgcmlnaHQobm9kZSkge1xuICAgICAgICB0aGlzLl9yaWdodCA9IG5vZGU7XG4gICAgICAgIGlmIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnBhcmVudCA9IHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgdGhpcy51cGRhdGVNYXgoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogbnVsbCBvdXQgcmVmZXJlbmNlcy5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9yaWdodCA9IG51bGw7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBudWxsO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUludGVydmFsVGltZWxpbmUuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vY2xvY2svQ2xvY2tcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL2Nsb2NrL1RyYW5zcG9ydFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Db250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0Jhc2VDb250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0RlbGF5XCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0Rlc3RpbmF0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0dhaW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9QYXJhbVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL0ZyZXF1ZW5jeVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9NaWRpXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL1RpbWVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVGlja3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IFwiLi91dGlsL0RyYXdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvRW1pdHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9JbnRlcnZhbFRpbWVsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvVHlwZUNoZWNrXCI7XG5leHBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIsIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbywgZnRvbSwgbXRvZiB9IGZyb20gXCIuL3R5cGUvQ29udmVyc2lvbnNcIjtcbmV4cG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzLCBkZWZhdWx0QXJnIH0gZnJvbSBcIi4vdXRpbC9EZWZhdWx0c1wiO1xuLy8gZ2V0IHRoZSB1bml0cyBhbmQgZXhwb3J0IHRoZW0gdW5kZXIgdGhlIFwiVW5pdFwiIG5hbWVzcGFjZVxuaW1wb3J0ICogYXMgVW5pdCBmcm9tIFwiLi90eXBlL1VuaXRzXCI7XG5leHBvcnQgeyBVbml0IH07XG4vLyBleHBvcnQgdGhlIGRlYnVnIHN0dWZmIGFzIERlYnVnXG5pbXBvcnQgKiBhcyBkZWJ1ZyBmcm9tIFwiLi91dGlsL0RlYnVnXCI7XG5leHBvcnQgeyBkZWJ1ZyB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFZvbHVtZSBpcyBhIHNpbXBsZSB2b2x1bWUgbm9kZSwgdXNlZnVsIGZvciBjcmVhdGluZyBhIHZvbHVtZSBmYWRlci5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgdm9sID0gbmV3IFRvbmUuVm9sdW1lKC0xMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3Qodm9sKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgVm9sdW1lIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFZvbHVtZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlZvbHVtZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVm9sdW1lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLm91dHB1dC5nYWluO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IG9wdGlvbnMudm9sdW1lO1xuICAgICAgICAvLyBzZXQgdGhlIG11dGUgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgdm9sID0gbmV3IFRvbmUuVm9sdW1lKC0xMikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHZvbCkuc3RhcnQoKTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiB2b2wubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZvbHVtZS52YWx1ZSA9PT0gLUluZmluaXR5O1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5tdXRlICYmIG11dGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3VubXV0ZWRWb2x1bWUgPSB0aGlzLnZvbHVtZS52YWx1ZTtcbiAgICAgICAgICAgIC8vIG1heWJlIGl0IHNob3VsZCByYW1wIGhlcmU/XG4gICAgICAgICAgICB0aGlzLnZvbHVtZS52YWx1ZSA9IC1JbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLm11dGUgJiYgIW11dGUpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lLnZhbHVlID0gdGhpcy5fdW5tdXRlZFZvbHVtZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Vm9sdW1lLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi8uLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4vR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQSBzaW5nbGUgbWFzdGVyIG91dHB1dCB3aGljaCBpcyBjb25uZWN0ZWQgdG8gdGhlXG4gKiBBdWRpb0Rlc3RpbmF0aW9uTm9kZSAoYWthIHlvdXIgc3BlYWtlcnMpLlxuICogSXQgcHJvdmlkZXMgdXNlZnVsIGNvbnZlbmllbmNlcyBzdWNoIGFzIHRoZSBhYmlsaXR5XG4gKiB0byBzZXQgdGhlIHZvbHVtZSBhbmQgbXV0ZSB0aGUgZW50aXJlIGFwcGxpY2F0aW9uLlxuICogSXQgYWxzbyBnaXZlcyB5b3UgdGhlIGFiaWxpdHkgdG8gYXBwbHkgbWFzdGVyIGVmZmVjdHMgdG8geW91ciBhcHBsaWNhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5zdGFydCgpO1xuICogLy8gdGhlIGF1ZGlvIHdpbGwgZ28gZnJvbSB0aGUgb3NjaWxsYXRvciB0byB0aGUgc3BlYWtlcnNcbiAqIG9zY2lsbGF0b3IuY29ubmVjdChUb25lLmdldERlc3RpbmF0aW9uKCkpO1xuICogLy8gYSBjb252ZW5pZW5jZSBmb3IgY29ubmVjdGluZyB0byB0aGUgbWFzdGVyIG91dHB1dCBpcyBhbHNvIHByb3ZpZGVkOlxuICogb3NjaWxsYXRvci50b0Rlc3RpbmF0aW9uKCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRGVzdGluYXRpb24gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVzdGluYXRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGVzdGluYXRpb25cIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBWb2x1bWUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdm9sdW1lIG9mIHRoZSBtYXN0ZXIgb3V0cHV0IGluIGRlY2liZWxzLiAtSW5maW5pdHkgaXMgc2lsZW50LCBhbmQgMCBpcyBubyBjaGFuZ2UuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAqIG9zYy5zdGFydCgpO1xuICAgICAgICAgKiAvLyByYW1wIHRoZSB2b2x1bWUgZG93biB0byBzaWxlbnQgb3ZlciAxMCBzZWNvbmRzXG4gICAgICAgICAqIFRvbmUuZ2V0RGVzdGluYXRpb24oKS52b2x1bWUucmFtcFRvKC1JbmZpbml0eSwgMTApO1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLmlucHV0LnZvbHVtZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERlc3RpbmF0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgdGhpcy5vdXRwdXQsIHRoaXMuY29udGV4dC5yYXdDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuaW5wdXQsIHRoaXMuY29udGV4dC5yYXdDb250ZXh0LmRlc3RpbmF0aW9uLCB0aGlzLm91dHB1dF07XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICogXHQvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBcdFRvbmUuRGVzdGluYXRpb24ubXV0ZSA9IHRydWU7XG4gICAgICogfSwgMTAwMCk7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0Lm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5pbnB1dC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgbWFzdGVyIGVmZmVjdHMgY2hhaW4uIE5PVEU6IHRoaXMgd2lsbCBkaXNjb25uZWN0IGFueSBub2RlcyB3aGljaCB3ZXJlIHByZXZpb3VzbHlcbiAgICAgKiBjaGFpbmVkIGluIHRoZSBtYXN0ZXIgZWZmZWN0cyBjaGFpbi5cbiAgICAgKiBAcGFyYW0gYXJncyBBbGwgYXJndW1lbnRzIHdpbGwgYmUgY29ubmVjdGVkIGluIGEgcm93IGFuZCB0aGUgTWFzdGVyIHdpbGwgYmUgcm91dGVkIHRocm91Z2ggaXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyByb3V0ZSBhbGwgYXVkaW8gdGhyb3VnaCBhIGZpbHRlciBhbmQgY29tcHJlc3NvclxuICAgICAqIGNvbnN0IGxvd3Bhc3MgPSBuZXcgVG9uZS5GaWx0ZXIoODAwLCBcImxvd3Bhc3NcIik7XG4gICAgICogY29uc3QgY29tcHJlc3NvciA9IG5ldyBUb25lLkNvbXByZXNzb3IoLTE4KTtcbiAgICAgKiBUb25lLkRlc3RpbmF0aW9uLmNoYWluKGxvd3Bhc3MsIGNvbXByZXNzb3IpO1xuICAgICAqL1xuICAgIGNoYWluKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgIGFyZ3MudW5zaGlmdCh0aGlzLmlucHV0KTtcbiAgICAgICAgYXJncy5wdXNoKHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29ubmVjdFNlcmllcyguLi5hcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFubmVscyB0aGUgc3lzdGVtIGNhbiBvdXRwdXRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuRGVzdGluYXRpb24ubWF4Q2hhbm5lbENvdW50KTtcbiAgICAgKi9cbiAgICBnZXQgbWF4Q2hhbm5lbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24ubWF4Q2hhbm5lbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRlc3RpbmF0aW9uID0gbmV3IERlc3RpbmF0aW9uKHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kZXN0aW5hdGlvbi5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlc3RpbmF0aW9uLmpzLm1hcCIsImltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2luZ2xlIHZhbHVlIHdoaWNoIGlzIGdldHRhYmxlIGFuZCBzZXR0YWJsZSBpbiBhIHRpbWVkIHdheVxuICovXG5leHBvcnQgY2xhc3MgVGltZWxpbmVWYWx1ZSBleHRlbmRzIFRvbmUge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBpbml0aWFsVmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBpZiB0aGVyZSBpcyBubyBzY2hlZHVsZWQgdmFsdWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoaW5pdGlhbFZhbHVlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGltZWxpbmVWYWx1ZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVsaW5lIHdoaWNoIHN0b3JlcyB0aGUgdmFsdWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lbGluZSA9IG5ldyBUaW1lbGluZSh7IG1lbW9yeTogMTAgfSk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqL1xuICAgIHNldCh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5hZGQoe1xuICAgICAgICAgICAgdmFsdWUsIHRpbWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICovXG4gICAgZ2V0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZS5nZXQodGltZSk7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWVsaW5lVmFsdWUuanMubWFwIiwiaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBUcmFuc3BvcnRFdmVudCBpcyBhbiBpbnRlcm5hbCBjbGFzcyB1c2VkIGJ5IFtbVHJhbnNwb3J0XV1cbiAqIHRvIHNjaGVkdWxlIGV2ZW50cy4gRG8gbm8gaW52b2tlIHRoaXMgY2xhc3MgZGlyZWN0bHksIGl0IGlzXG4gKiBoYW5kbGVkIGZyb20gd2l0aGluIFRvbmUuVHJhbnNwb3J0LlxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0RXZlbnQge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB0cmFuc3BvcnQgVGhlIHRyYW5zcG9ydCBvYmplY3Qgd2hpY2ggdGhlIGV2ZW50IGJlbG9uZ3MgdG9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0cmFuc3BvcnQsIG9wdHMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB1bmlxdWUgaWQgb2YgdGhlIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlkID0gVHJhbnNwb3J0RXZlbnQuX2V2ZW50SWQrKztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oVHJhbnNwb3J0RXZlbnQuZ2V0RGVmYXVsdHMoKSwgb3B0cyk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fb25jZSA9IG9wdGlvbnMub25jZTtcbiAgICAgICAgdGhpcy50aW1lID0gb3B0aW9ucy50aW1lO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIG9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBldmVudCBjYWxsYmFjay5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBBdWRpb0NvbnRleHQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIGludm9rZSh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29uY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogQ3VycmVudCBJRCBjb3VudGVyXG4gKi9cblRyYW5zcG9ydEV2ZW50Ll9ldmVudElkID0gMDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydEV2ZW50LmpzLm1hcCIsImltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRFdmVudFwiO1xuLyoqXG4gKiBUcmFuc3BvcnRSZXBlYXRFdmVudCBpcyBhbiBpbnRlcm5hbCBjbGFzcyB1c2VkIGJ5IFRvbmUuVHJhbnNwb3J0XG4gKiB0byBzY2hlZHVsZSByZXBlYXQgZXZlbnRzLiBUaGlzIGNsYXNzIHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LlxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0UmVwZWF0RXZlbnQgZXh0ZW5kcyBUcmFuc3BvcnRFdmVudCB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHRyYW5zcG9ydCBUaGUgdHJhbnNwb3J0IG9iamVjdCB3aGljaCB0aGUgZXZlbnQgYmVsb25ncyB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgb3B0cykge1xuICAgICAgICBzdXBlcih0cmFuc3BvcnQsIG9wdHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIElEIG9mIHRoZSBjdXJyZW50IHRpbWVsaW5lIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRCBvZiB0aGUgbmV4dCB0aW1lbGluZSBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmV4dElkID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZSBvZiB0aGUgbmV4dCBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhIHJlZmVyZW5jZSB0byB0aGUgYm91bmQgc3RhcnQgbWV0aG9kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZFJlc3RhcnQgPSB0aGlzLl9yZXN0YXJ0LmJpbmQodGhpcyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFRyYW5zcG9ydFJlcGVhdEV2ZW50LmdldERlZmF1bHRzKCksIG9wdHMpO1xuICAgICAgICB0aGlzLmR1cmF0aW9uID0gbmV3IFRpY2tzQ2xhc3ModHJhbnNwb3J0LmNvbnRleHQsIG9wdGlvbnMuZHVyYXRpb24pLnZhbHVlT2YoKTtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBuZXcgVGlja3NDbGFzcyh0cmFuc3BvcnQuY29udGV4dCwgb3B0aW9ucy5pbnRlcnZhbCkudmFsdWVPZigpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IG9wdGlvbnMudGltZTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vbihcImxvb3BTdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSB0aGlzLnRyYW5zcG9ydC5jb250ZXh0O1xuICAgICAgICB0aGlzLl9yZXN0YXJ0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIFRyYW5zcG9ydEV2ZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiBJbmZpbml0eSxcbiAgICAgICAgICAgIGludGVydmFsOiAxLFxuICAgICAgICAgICAgb25jZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrLiBSZXR1cm5zIHRoZSB0aWNrIHRpbWUgd2hpY2hcbiAgICAgKiB0aGUgbmV4dCBldmVudCBzaG91bGQgYmUgc2NoZWR1bGVkIGF0LlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIEF1ZGlvQ29udGV4dCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgaW52b2tlKHRpbWUpIHtcbiAgICAgICAgLy8gY3JlYXRlIG1vcmUgZXZlbnRzIGlmIG5lY2Vzc2FyeVxuICAgICAgICB0aGlzLl9jcmVhdGVFdmVudHModGltZSk7XG4gICAgICAgIC8vIGNhbGwgdGhlIHN1cGVyIGNsYXNzXG4gICAgICAgIHN1cGVyLmludm9rZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHVzaCBtb3JlIGV2ZW50cyBvbnRvIHRoZSB0aW1lbGluZSB0byBrZWVwIHVwIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIF9jcmVhdGVFdmVudHModGltZSkge1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgbmV4dCBldmVudFxuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAodGlja3MgPj0gdGhpcy50aW1lICYmIHRpY2tzID49IHRoaXMuX25leHRUaWNrICYmIHRoaXMuX25leHRUaWNrICsgdGhpcy5faW50ZXJ2YWwgPCB0aGlzLnRpbWUgKyB0aGlzLmR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9uZXh0VGljayArPSB0aGlzLl9pbnRlcnZhbDtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IHRoaXMuX25leHRJZDtcbiAgICAgICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUHVzaCBtb3JlIGV2ZW50cyBvbnRvIHRoZSB0aW1lbGluZSB0byBrZWVwIHVwIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fY3VycmVudElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWU7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aWNrcyA+IHRoaXMudGltZSkge1xuICAgICAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWUgKyBNYXRoLmNlaWwoKHRpY2tzIC0gdGhpcy50aW1lKSAvIHRoaXMuX2ludGVydmFsKSAqIHRoaXMuX2ludGVydmFsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuICAgICAgICB0aGlzLl9uZXh0SWQgPSB0aGlzLnRyYW5zcG9ydC5zY2hlZHVsZU9uY2UodGhpcy5pbnZva2UuYmluZCh0aGlzKSwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9uZXh0VGljaykudG9TZWNvbmRzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fY3VycmVudElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub2ZmKFwibG9vcFN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydFJlcGVhdEV2ZW50LmpzLm1hcCIsImltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvVGltZVwiO1xuaW1wb3J0IHsgVGltZWxpbmVWYWx1ZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVGltZWxpbmVWYWx1ZVwiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi4vY29udGV4dC9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgSW50ZXJ2YWxUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL0ludGVydmFsVGltZWxpbmVcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgQ2xvY2sgfSBmcm9tIFwiLi9DbG9ja1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRFdmVudFwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0UmVwZWF0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRSZXBlYXRFdmVudFwiO1xuLyoqXG4gKiBUcmFuc3BvcnQgZm9yIHRpbWluZyBtdXNpY2FsIGV2ZW50cy5cbiAqIFN1cHBvcnRzIHRlbXBvIGN1cnZlcyBhbmQgdGltZSBjaGFuZ2VzLiBVbmxpa2UgYnJvd3Nlci1iYXNlZCB0aW1pbmcgKHNldEludGVydmFsLCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpXG4gKiBUcmFuc3BvcnQgdGltaW5nIGV2ZW50cyBwYXNzIGluIHRoZSBleGFjdCB0aW1lIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnRcbiAqIGluIHRoZSBhcmd1bWVudCBvZiB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uIFBhc3MgdGhhdCB0aW1lIHZhbHVlIHRvIHRoZSBvYmplY3RcbiAqIHlvdSdyZSBzY2hlZHVsaW5nLiA8YnI+PGJyPlxuICogQSBzaW5nbGUgdHJhbnNwb3J0IGlzIGNyZWF0ZWQgZm9yIHlvdSB3aGVuIHRoZSBsaWJyYXJ5IGlzIGluaXRpYWxpemVkLlxuICogPGJyPjxicj5cbiAqIFRoZSB0cmFuc3BvcnQgZW1pdHMgdGhlIGV2ZW50czogXCJzdGFydFwiLCBcInN0b3BcIiwgXCJwYXVzZVwiLCBhbmQgXCJsb29wXCIgd2hpY2ggYXJlXG4gKiBjYWxsZWQgd2l0aCB0aGUgdGltZSBvZiB0aGF0IGV2ZW50IGFzIHRoZSBhcmd1bWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHJlcGVhdGVkIGV2ZW50IGV2ZXJ5IDh0aCBub3RlXG4gKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCgodGltZSkgPT4ge1xuICogXHQvLyB1c2UgdGhlIGNhbGxiYWNrIHRpbWUgdG8gc2NoZWR1bGUgZXZlbnRzXG4gKiBcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICogfSwgXCI4blwiKTtcbiAqIC8vIHRyYW5zcG9ydCBtdXN0IGJlIHN0YXJ0ZWQgYmVmb3JlIGl0IHN0YXJ0cyBpbnZva2luZyBldmVudHNcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJhbnNwb3J0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyYW5zcG9ydFwiO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRMT09QSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIHRyYW5zcG9ydCBsb29wcyBvciBub3QuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wID0gbmV3IFRpbWVsaW5lVmFsdWUoZmFsc2UpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvb3Agc3RhcnQgcG9zaXRpb24gaW4gdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG9vcCBlbmQgcG9zaXRpb24gaW4gdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRUSU1FTElORSBFVkVOVFNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgdGhlIGV2ZW50cyBpbiBhbiBvYmplY3QgdG8ga2VlcCB0cmFjayBieSBJRFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0ge307XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2NoZWR1bGVkIGV2ZW50cy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXBlYXRlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzID0gbmV3IEludGVydmFsVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgc3luY2VkIFNpZ25hbHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzd2luZyBhbW91bnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyYW5zcG9ydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICAvLyBDTE9DSy9URU1QT1xuICAgICAgICB0aGlzLl9wcHEgPSBvcHRpb25zLnBwcTtcbiAgICAgICAgdGhpcy5fY2xvY2sgPSBuZXcgQ2xvY2soe1xuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3Byb2Nlc3NUaWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB1bml0czogXCJicG1cIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2JpbmRDbG9ja0V2ZW50cygpO1xuICAgICAgICB0aGlzLmJwbSA9IHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXIgPSBvcHRpb25zLnBwcTtcbiAgICAgICAgdGhpcy5icG0uc2V0VmFsdWVBdFRpbWUob3B0aW9ucy5icG0sIDApO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImJwbVwiKTtcbiAgICAgICAgdGhpcy5fdGltZVNpZ25hdHVyZSA9IG9wdGlvbnMudGltZVNpZ25hdHVyZTtcbiAgICAgICAgLy8gU1dJTkdcbiAgICAgICAgdGhpcy5fc3dpbmdUaWNrcyA9IG9wdGlvbnMucHBxIC8gMjsgLy8gOG5cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYnBtOiAxMjAsXG4gICAgICAgICAgICBsb29wRW5kOiBcIjRtXCIsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBwcHE6IDE5MixcbiAgICAgICAgICAgIHN3aW5nOiAwLFxuICAgICAgICAgICAgc3dpbmdTdWJkaXZpc2lvbjogXCI4blwiLFxuICAgICAgICAgICAgdGltZVNpZ25hdHVyZTogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VElDS1NcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBjYWxsZWQgb24gZXZlcnkgdGlja1xuICAgICAqIEBwYXJhbSAgdGlja1RpbWUgY2xvY2sgcmVsYXRpdmUgdGljayB0aW1lXG4gICAgICovXG4gICAgX3Byb2Nlc3NUaWNrKHRpY2tUaW1lLCB0aWNrcykge1xuICAgICAgICAvLyBkbyB0aGUgbG9vcCB0ZXN0XG4gICAgICAgIGlmICh0aGlzLl9sb29wLmdldCh0aWNrVGltZSkpIHtcbiAgICAgICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLl9sb29wRW5kKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcEVuZFwiLCB0aWNrVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodGhpcy5fbG9vcFN0YXJ0LCB0aWNrVGltZSk7XG4gICAgICAgICAgICAgICAgdGlja3MgPSB0aGlzLl9sb29wU3RhcnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcFN0YXJ0XCIsIHRpY2tUaW1lLCB0aGlzLl9jbG9jay5nZXRTZWNvbmRzQXRUaW1lKHRpY2tUaW1lKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcFwiLCB0aWNrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaGFuZGxlIHN3aW5nXG4gICAgICAgIGlmICh0aGlzLl9zd2luZ0Ftb3VudCA+IDAgJiZcbiAgICAgICAgICAgIHRpY2tzICUgdGhpcy5fcHBxICE9PSAwICYmIC8vIG5vdCBvbiBhIGRvd25iZWF0XG4gICAgICAgICAgICB0aWNrcyAlICh0aGlzLl9zd2luZ1RpY2tzICogMikgIT09IDApIHtcbiAgICAgICAgICAgIC8vIGFkZCBzb21lIHN3aW5nXG4gICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9ICh0aWNrcyAlICh0aGlzLl9zd2luZ1RpY2tzICogMikpIC8gKHRoaXMuX3N3aW5nVGlja3MgKiAyKTtcbiAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IE1hdGguc2luKChwcm9ncmVzcykgKiBNYXRoLlBJKSAqIHRoaXMuX3N3aW5nQW1vdW50O1xuICAgICAgICAgICAgdGlja1RpbWUgKz0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zd2luZ1RpY2tzICogMiAvIDMpLnRvU2Vjb25kcygpICogYW1vdW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIGludm9rZSB0aGUgdGltZWxpbmUgZXZlbnRzIHNjaGVkdWxlZCBvbiB0aGlzIHRpY2tcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZm9yRWFjaEF0VGltZSh0aWNrcywgZXZlbnQgPT4gZXZlbnQuaW52b2tlKHRpY2tUaW1lKSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U0NIRURVTEFCTEUgRVZFTlRTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYW4gZXZlbnQgYWxvbmcgdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCBhdCB0aGUgdGltZS5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0byBpbnZva2UgdGhlIGNhbGxiYWNrIGF0LlxuICAgICAqIEByZXR1cm4gVGhlIGlkIG9mIHRoZSBldmVudCB3aGljaCBjYW4gYmUgdXNlZCBmb3IgY2FuY2VsaW5nIHRoZSBldmVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHNjaGVkdWxlIGFuIGV2ZW50IG9uIHRoZSAxNnRoIG1lYXN1cmVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZSgodGltZSkgPT4ge1xuICAgICAqIFx0Ly8gaW52b2tlZCBvbiBtZWFzdXJlIDE2XG4gICAgICogXHRjb25zb2xlLmxvZyhcIm1lYXN1cmUgMTYhXCIpO1xuICAgICAqIH0sIFwiMTY6MDowXCIpO1xuICAgICAqL1xuICAgIHNjaGVkdWxlKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IFRyYW5zcG9ydEV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgdGltZTogbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fdGltZWxpbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhIHJlcGVhdGVkIGV2ZW50IGFsb25nIHRoZSB0aW1lbGluZS4gVGhlIGV2ZW50IHdpbGwgZmlyZVxuICAgICAqIGF0IHRoZSBgaW50ZXJ2YWxgIHN0YXJ0aW5nIGF0IHRoZSBgc3RhcnRUaW1lYCBhbmQgZm9yIHRoZSBzcGVjaWZpZWRcbiAgICAgKiBgZHVyYXRpb25gLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSAgaW50ZXJ2YWwgICBUaGUgZHVyYXRpb24gYmV0d2VlbiBzdWNjZXNzaXZlIGNhbGxiYWNrcy4gTXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlci5cbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSAgV2hlbiBhbG9uZyB0aGUgdGltZWxpbmUgdGhlIGV2ZW50cyBzaG91bGQgc3RhcnQgYmVpbmcgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBldmVudCBzaG91bGQgcmVwZWF0LlxuICAgICAqIEByZXR1cm4gIFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50LiBVc2UgdGhpcyB0byBjYW5jZWwgdGhlIGV2ZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIGEgY2FsbGJhY2sgaW52b2tlZCBldmVyeSBlaWdodGggbm90ZSBhZnRlciB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KCh0aW1lKSA9PiB7XG4gICAgICogXHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAgICAgKiB9LCBcIjhuXCIsIFwiMW1cIik7XG4gICAgICovXG4gICAgc2NoZWR1bGVSZXBlYXQoY2FsbGJhY2ssIGludGVydmFsLCBzdGFydFRpbWUsIGR1cmF0aW9uID0gSW5maW5pdHkpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0UmVwZWF0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICBkdXJhdGlvbjogbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGR1cmF0aW9uKS50b1RpY2tzKCksXG4gICAgICAgICAgICBpbnRlcnZhbDogbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGludGVydmFsKS50b1RpY2tzKCksXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1RpY2tzKCksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBraWNrIGl0IG9mZiBpZiB0aGUgVHJhbnNwb3J0IGlzIHN0YXJ0ZWRcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3JlcGVhdGVkRXZlbnRzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYW4gZXZlbnQgdGhhdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSBvbmNlLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRoZSBjYWxsYmFjayBzaG91bGQgYmUgaW52b2tlZC5cbiAgICAgKiBAcmV0dXJucyBUaGUgSUQgb2YgdGhlIHNjaGVkdWxlZCBldmVudC5cbiAgICAgKi9cbiAgICBzY2hlZHVsZU9uY2UoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICBvbmNlOiB0cnVlLFxuICAgICAgICAgICAgdGltZTogbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fdGltZWxpbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciB0aGUgcGFzc2VkIGluIGV2ZW50IGlkIGZyb20gdGhlIHRpbWVsaW5lXG4gICAgICogQHBhcmFtIGV2ZW50SWQgVGhlIGlkIG9mIHRoZSBldmVudC5cbiAgICAgKi9cbiAgICBjbGVhcihldmVudElkKSB7XG4gICAgICAgIGlmICh0aGlzLl9zY2hlZHVsZWRFdmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnRJZCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcbiAgICAgICAgICAgIGl0ZW0udGltZWxpbmUucmVtb3ZlKGl0ZW0uZXZlbnQpO1xuICAgICAgICAgICAgaXRlbS5ldmVudC5kaXNwb3NlKCk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50SWQudG9TdHJpbmcoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBldmVudCB0byB0aGUgY29ycmVjdCB0aW1lbGluZS4gS2VlcCB0cmFjayBvZiB0aGVcbiAgICAgKiB0aW1lbGluZSBpdCB3YXMgYWRkZWQgdG8uXG4gICAgICogQHJldHVybnMgdGhlIGV2ZW50IGlkIHdoaWNoIHdhcyBqdXN0IGFkZGVkXG4gICAgICovXG4gICAgX2FkZEV2ZW50KGV2ZW50LCB0aW1lbGluZSkge1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnQuaWQudG9TdHJpbmcoKV0gPSB7XG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRpbWVsaW5lLFxuICAgICAgICB9O1xuICAgICAgICB0aW1lbGluZS5hZGQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gZXZlbnQuaWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBzY2hlZHVsZWQgZXZlbnRzIGZyb20gdGhlIHRpbWVsaW5lIGFmdGVyXG4gICAgICogdGhlIGdpdmVuIHRpbWUuIFJlcGVhdGVkIGV2ZW50cyB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBpZiB0aGVpciBzdGFydFRpbWUgaXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gYWZ0ZXIgQ2xlYXIgYWxsIGV2ZW50cyBhZnRlciB0aGlzIHRpbWUuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyID0gMCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZEFmdGVyID0gdGhpcy50b1RpY2tzKGFmdGVyKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZm9yRWFjaEZyb20oY29tcHV0ZWRBZnRlciwgZXZlbnQgPT4gdGhpcy5jbGVhcihldmVudC5pZCkpO1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5mb3JFYWNoRnJvbShjb21wdXRlZEFmdGVyLCBldmVudCA9PiB0aGlzLmNsZWFyKGV2ZW50LmlkKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNUQVJUL1NUT1AvUEFVU0VcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBCaW5kIHN0YXJ0L3N0b3AvcGF1c2UgZXZlbnRzIGZyb20gdGhlIGNsb2NrIGFuZCBlbWl0IHRoZW0uXG4gICAgICovXG4gICAgX2JpbmRDbG9ja0V2ZW50cygpIHtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdGFydFwiLCAodGltZSwgb2Zmc2V0KSA9PiB7XG4gICAgICAgICAgICBvZmZzZXQgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIG9mZnNldCkudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCB0aW1lLCBvZmZzZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdG9wXCIsICh0aW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIHRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJwYXVzZVwiLCAodGltZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgdGltZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiLCBvciBcInBhdXNlZFwiXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB3aGVuIHRoZSB0cmFuc3BvcnQgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSB0aW1lbGluZSBvZmZzZXQgdG8gc3RhcnQgdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHN0YXJ0IHRoZSB0cmFuc3BvcnQgaW4gb25lIHNlY29uZCBzdGFydGluZyBhdCBiZWdpbm5pbmcgb2YgdGhlIDV0aCBtZWFzdXJlLlxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KFwiKzFcIiwgXCI0OjA6MFwiKTtcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgbGV0IG9mZnNldFRpY2tzO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKG9mZnNldCkpIHtcbiAgICAgICAgICAgIG9mZnNldFRpY2tzID0gdGhpcy50b1RpY2tzKG9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdGhlIGNsb2NrXG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0YXJ0KHRpbWUsIG9mZnNldFRpY2tzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgdHJhbnNwb3J0IHNob3VsZCBzdG9wLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RvcCgpO1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5wYXVzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRvZ2dsZSB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgdHJhbnNwb3J0LiBJZiBpdCBpc1xuICAgICAqIHN0YXJ0ZWQsIGl0IHdpbGwgc3RvcCBpdCwgb3RoZXJ3aXNlIGl0IHdpbGwgc3RhcnQgdGhlIFRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdG9nZ2xlKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fY2xvY2suZ2V0U3RhdGVBdFRpbWUodGltZSkgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0KHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNFVFRFUlMvR0VUVEVSU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHNpZ25hdHVyZSBhcyBqdXN0IHRoZSBudW1lcmF0b3Igb3ZlciA0LlxuICAgICAqIEZvciBleGFtcGxlIDQvNCB3b3VsZCBiZSBqdXN0IDQgYW5kIDYvOCB3b3VsZCBiZSAzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gY29tbW9uIHRpbWVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlID0gNDtcbiAgICAgKiAvLyA3LzhcbiAgICAgKiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlID0gWzcsIDhdO1xuICAgICAqIC8vIHRoaXMgd2lsbCBiZSByZWR1Y2VkIHRvIGEgc2luZ2xlIG51bWJlclxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmU7IC8vIHJldHVybnMgMy41XG4gICAgICovXG4gICAgZ2V0IHRpbWVTaWduYXR1cmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lU2lnbmF0dXJlO1xuICAgIH1cbiAgICBzZXQgdGltZVNpZ25hdHVyZSh0aW1lU2lnKSB7XG4gICAgICAgIGlmIChpc0FycmF5KHRpbWVTaWcpKSB7XG4gICAgICAgICAgICB0aW1lU2lnID0gKHRpbWVTaWdbMF0gLyB0aW1lU2lnWzFdKSAqIDQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGltZVNpZ25hdHVyZSA9IHRpbWVTaWc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIFRyYW5zcG9ydC5sb29wID0gdHJ1ZSwgdGhpcyBpcyB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wU3RhcnQsIFwiaVwiKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChzdGFydFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhzdGFydFBvc2l0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgdGhlIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChlbmRQb3NpdGlvbikge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGVuZFBvc2l0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHRyYW5zcG9ydCBsb29wcyBvciBub3QuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wLmdldCh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wLnNldChsb29wLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsb29wIHN0YXJ0IGFuZCBzdG9wIGF0IHRoZSBzYW1lIHRpbWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb29wIG92ZXIgdGhlIGZpcnN0IG1lYXN1cmVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zZXRMb29wUG9pbnRzKDAsIFwiMW1cIik7XG4gICAgICogVG9uZS5UcmFuc3BvcnQubG9vcCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0TG9vcFBvaW50cyhzdGFydFBvc2l0aW9uLCBlbmRQb3NpdGlvbikge1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IHN0YXJ0UG9zaXRpb247XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IGVuZFBvc2l0aW9uO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN3aW5nIHZhbHVlLiBCZXR3ZWVuIDAtMSB3aGVyZSAxIGVxdWFsIHRvIHRoZSBub3RlICsgaGFsZiB0aGUgc3ViZGl2aXNpb24uXG4gICAgICovXG4gICAgZ2V0IHN3aW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3dpbmdBbW91bnQ7XG4gICAgfVxuICAgIHNldCBzd2luZyhhbW91bnQpIHtcbiAgICAgICAgLy8gc2NhbGUgdGhlIHZhbHVlcyB0byBhIG5vcm1hbCByYW5nZVxuICAgICAgICB0aGlzLl9zd2luZ0Ftb3VudCA9IGFtb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBzdWJkaXZpc2lvbiB3aGljaCB0aGUgc3dpbmcgd2lsbCBiZSBhcHBsaWVkIHRvLlxuICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGFuIDh0aCBub3RlLiBWYWx1ZSBtdXN0IGJlIGxlc3NcbiAgICAgKiB0aGFuIGEgcXVhcnRlciBub3RlLlxuICAgICAqL1xuICAgIGdldCBzd2luZ1N1YmRpdmlzaW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zd2luZ1RpY2tzKS50b05vdGF0aW9uKCk7XG4gICAgfVxuICAgIHNldCBzd2luZ1N1YmRpdmlzaW9uKHN1YmRpdmlzaW9uKSB7XG4gICAgICAgIHRoaXMuX3N3aW5nVGlja3MgPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgcG9zaXRpb24gaW4gQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuICAgICAqIFNldHRpbmcgdGhlIHZhbHVlIHdpbGwganVtcCB0byB0aGF0IHBvc2l0aW9uIHJpZ2h0IGF3YXkuXG4gICAgICovXG4gICAgZ2V0IHBvc2l0aW9uKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKG5vdyk7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKS50b0JhcnNCZWF0c1NpeHRlZW50aHMoKTtcbiAgICB9XG4gICAgc2V0IHBvc2l0aW9uKHByb2dyZXNzKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHByb2dyZXNzKTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgcG9zaXRpb24gaW4gc2Vjb25kc1xuICAgICAqIFNldHRpbmcgdGhlIHZhbHVlIHdpbGwganVtcCB0byB0aGF0IHBvc2l0aW9uIHJpZ2h0IGF3YXkuXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5zZWNvbmRzO1xuICAgIH1cbiAgICBzZXQgc2Vjb25kcyhzKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5LnRpbWVUb1RpY2tzKHMsIG5vdyk7XG4gICAgICAgIHRoaXMudGlja3MgPSB0aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFRyYW5zcG9ydCdzIGxvb3AgcG9zaXRpb24gYXMgYSBub3JtYWxpemVkIHZhbHVlLiBBbHdheXNcbiAgICAgKiByZXR1cm5zIDAgaWYgdGhlIHRyYW5zcG9ydCBpZiBsb29wIGlzIG5vdCB0cnVlLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgIHJldHVybiAodGlja3MgLSB0aGlzLl9sb29wU3RhcnQpIC8gKHRoaXMuX2xvb3BFbmQgLSB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zcG9ydHMgY3VycmVudCB0aWNrIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCB0aWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnRpY2tzO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICBpZiAodGhpcy5fY2xvY2sudGlja3MgIT09IHQpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICAvLyBzdG9wIGV2ZXJ5dGhpbmcgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgICAgICAvLyBzY2hlZHVsZSB0byBzdGFydCBvbiB0aGUgbmV4dCB0aWNrLCAjNTczXG4gICAgICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVGljayA9IHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5nZXREdXJhdGlvbk9mVGlja3MoTWF0aC5jZWlsKHRpY2tzKSAtIHRpY2tzLCBub3cpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSBub3cgKyByZW1haW5pbmdUaWNrO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgdGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodCwgdGltZSk7XG4gICAgICAgICAgICAgICAgLy8gcmVzdGFydCBpdCB3aXRoIHRoZSBuZXcgdGltZVxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIHRpbWUsIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodCwgbm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIHRpY2sgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZSh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqIEByZXR1cm4gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG4gICAgICovXG4gICAgZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdWxzZXMgUGVyIFF1YXJ0ZXIgbm90ZS4gVGhpcyBpcyB0aGUgc21hbGxlc3QgcmVzb2x1dGlvblxuICAgICAqIHRoZSBUcmFuc3BvcnQgdGltaW5nIHN1cHBvcnRzLiBUaGlzIHNob3VsZCBiZSBzZXQgb25jZVxuICAgICAqIG9uIGluaXRpYWxpemF0aW9uIGFuZCBub3Qgc2V0IGFnYWluLiBDaGFuZ2luZyB0aGlzIHZhbHVlXG4gICAgICogYWZ0ZXIgb3RoZXIgb2JqZWN0cyBoYXZlIGJlZW4gY3JlYXRlZCBjYW4gY2F1c2UgcHJvYmxlbXMuXG4gICAgICovXG4gICAgZ2V0IFBQUSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgUFBRKHBwcSkge1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllciA9IHBwcTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTWU5DSU5HXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGltZSBhbGlnbmVkIHRvIHRoZSBuZXh0IHN1YmRpdmlzaW9uXG4gICAgICogb2YgdGhlIFRyYW5zcG9ydC4gSWYgdGhlIFRyYW5zcG9ydCBpcyBub3Qgc3RhcnRlZCxcbiAgICAgKiBpdCB3aWxsIHJldHVybiAwLlxuICAgICAqIE5vdGU6IHRoaXMgd2lsbCBub3Qgd29yayBwcmVjaXNlbHkgZHVyaW5nIHRlbXBvIHJhbXBzLlxuICAgICAqIEBwYXJhbSAgc3ViZGl2aXNpb24gIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuICAgICAqIEByZXR1cm4gIFRoZSBjb250ZXh0IHRpbWUgb2YgdGhlIG5leHQgc3ViZGl2aXNpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyB0aGUgdHJhbnNwb3J0IG11c3QgYmUgc3RhcnRlZCwgb3RoZXJ3aXNlIHJldHVybnMgMFxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICogVG9uZS5UcmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKFwiNG5cIik7XG4gICAgICovXG4gICAgbmV4dFN1YmRpdmlzaW9uKHN1YmRpdmlzaW9uKSB7XG4gICAgICAgIHN1YmRpdmlzaW9uID0gdGhpcy50b1RpY2tzKHN1YmRpdmlzaW9uKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAvLyBpZiB0aGUgdHJhbnNwb3J0J3Mgbm90IHN0YXJ0ZWQsIHJldHVybiAwXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICAvLyB0aGUgcmVtYWluZGVyIG9mIHRoZSBjdXJyZW50IHRpY2tzIGFuZCB0aGUgc3ViZGl2aXNpb25cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zcG9ydFBvcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1RpY2tzID0gc3ViZGl2aXNpb24gLSB0cmFuc3BvcnRQb3MgJSBzdWJkaXZpc2lvbjtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5uZXh0VGlja1RpbWUocmVtYWluaW5nVGlja3MsIG5vdyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0YWNoZXMgdGhlIHNpZ25hbCB0byB0aGUgdGVtcG8gY29udHJvbCBzaWduYWwgc28gdGhhdFxuICAgICAqIGFueSBjaGFuZ2VzIGluIHRoZSB0ZW1wbyB3aWxsIGNoYW5nZSB0aGUgc2lnbmFsIGluIHRoZSBzYW1lXG4gICAgICogcmF0aW8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2lnbmFsXG4gICAgICogQHBhcmFtIHJhdGlvIE9wdGlvbmFsbHkgcGFzcyBpbiB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHNpZ25hbHMuXG4gICAgICogXHRcdFx0T3RoZXJ3aXNlIGl0IHdpbGwgYmUgY29tcHV0ZWQgYmFzZWQgb24gdGhlaXIgY3VycmVudCB2YWx1ZXMuXG4gICAgICovXG4gICAgc3luY1NpZ25hbChzaWduYWwsIHJhdGlvKSB7XG4gICAgICAgIGlmICghcmF0aW8pIHtcbiAgICAgICAgICAgIC8vIGdldCB0aGUgc3luYyByYXRpb1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGlmIChzaWduYWwuZ2V0VmFsdWVBdFRpbWUobm93KSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJwbSA9IHRoaXMuYnBtLmdldFZhbHVlQXRUaW1lKG5vdyk7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRGcmVxID0gMSAvICg2MCAvIGJwbSAvIHRoaXMuUFBRKTtcbiAgICAgICAgICAgICAgICByYXRpbyA9IHNpZ25hbC5nZXRWYWx1ZUF0VGltZShub3cpIC8gY29tcHV0ZWRGcmVxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmF0aW8gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJhdGlvU2lnbmFsID0gbmV3IEdhaW4ocmF0aW8pO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuYnBtLmNvbm5lY3QocmF0aW9TaWduYWwpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJhdGlvU2lnbmFsLmNvbm5lY3Qoc2lnbmFsLl9wYXJhbSk7XG4gICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMucHVzaCh7XG4gICAgICAgICAgICBpbml0aWFsOiBzaWduYWwudmFsdWUsXG4gICAgICAgICAgICByYXRpbzogcmF0aW9TaWduYWwsXG4gICAgICAgICAgICBzaWduYWwsXG4gICAgICAgIH0pO1xuICAgICAgICBzaWduYWwudmFsdWUgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jcyBhIHByZXZpb3VzbHkgc3luY2VkIHNpZ25hbCBmcm9tIHRoZSB0cmFuc3BvcnQncyBjb250cm9sLlxuICAgICAqIFNlZSBUcmFuc3BvcnQuc3luY1NpZ25hbC5cbiAgICAgKi9cbiAgICB1bnN5bmNTaWduYWwoc2lnbmFsKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLl9zeW5jZWRTaWduYWxzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBzeW5jZWRTaWduYWwgPSB0aGlzLl9zeW5jZWRTaWduYWxzW2ldO1xuICAgICAgICAgICAgaWYgKHN5bmNlZFNpZ25hbC5zaWduYWwgPT09IHNpZ25hbCkge1xuICAgICAgICAgICAgICAgIHN5bmNlZFNpZ25hbC5yYXRpby5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnNpZ25hbC52YWx1ZSA9IHN5bmNlZFNpZ25hbC5pbml0aWFsO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgXCJicG1cIik7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5FbWl0dGVyLm1peGluKFRyYW5zcG9ydCk7XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LnRyYW5zcG9ydCA9IG5ldyBUcmFuc3BvcnQoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LnRyYW5zcG9ydC5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydC5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgXCIuLi9jb3JlL2NvbnRleHQvRGVzdGluYXRpb25cIjtcbmltcG9ydCBcIi4uL2NvcmUvY2xvY2svVHJhbnNwb3J0XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc1VuZGVmIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0Q29udGV4dFJ1bm5pbmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBHVCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBzb3VyY2VzLlxuICogc3RhcnQvc3RvcCBvZiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LlxuICpcbiAqIGBgYFxuICogLy8gTXVsdGlwbGUgc3RhdGUgY2hhbmdlIGV2ZW50cyBjYW4gYmUgY2hhaW5lZCB0b2dldGhlcixcbiAqIC8vIGJ1dCBtdXN0IGJlIHNldCBpbiB0aGUgY29ycmVjdCBvcmRlciBhbmQgd2l0aCBhc2NlbmRpbmcgdGltZXNcbiAqIC8vIE9LXG4gKiBzdGF0ZS5zdGFydCgpLnN0b3AoXCIrMC4yXCIpO1xuICogLy8gT0tcbiAqIHN0YXRlLnN0YXJ0KCkuc3RvcChcIiswLjJcIikuc3RhcnQoXCIrMC40XCIpLnN0b3AoXCIrMC43XCIpXG4gKiAvLyBCQURcbiAqIHN0YXRlLnN0b3AoXCIrMC4yXCIpLnN0YXJ0KCk7XG4gKiAvLyBCQURcbiAqIHN0YXRlLnN0YXJ0KFwiKzAuM1wiKS5zdG9wKFwiKzAuMlwiKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU291cmNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNvdXJjZXMgaGF2ZSBubyBpbnB1dHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBzY2hlZHVsZWQgc3RhdGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzeW5jZWQgYHN0YXJ0YCBjYWxsYmFjayBmdW5jdGlvbiBmcm9tIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiBhbGwgb2YgdGhlIHNjaGVkdWxlZCBldmVudCBpZHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZCA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogUGxhY2Vob2xkZXIgZnVuY3Rpb25zIGZvciBzeW5jaW5nL3Vuc3luY2luZyB0byB0cmFuc3BvcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0ID0gbm9PcDtcbiAgICAgICAgdGhpcy5fc3luY2VkU3RvcCA9IG5vT3A7XG4gICAgICAgIHRoaXMuX3N0YXRlLm1lbW9yeSA9IDEwMDtcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5jcmVhc2luZyA9IHRydWU7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtdXRlOiBvcHRpb25zLm11dGUsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5vbnN0b3AgPSBvcHRpb25zLm9uc3RvcDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgb25zdG9wOiBub09wLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiIG9yIFwic3RvcHBlZFwiLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvYWhudG9uZV9jMy5tcDNcIiwgKCkgPT4ge1xuICAgICAqIFx0cGxheWVyLnN0YXJ0KCk7XG4gICAgICogXHRjb25zb2xlLmxvZyhwbGF5ZXIuc3RhdGUpO1xuICAgICAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RvcHBlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBvc2MubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuc3VyZSB0aGF0IHRoZSBzY2hlZHVsZWQgdGltZSBpcyBub3QgYmVmb3JlIHRoZSBjdXJyZW50IHRpbWUuXG4gICAgICogU2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIHNjaGVkdWxlZCB1bnN5bmNlZC5cbiAgICAgKi9cbiAgICBfY2xhbXBUb0N1cnJlbnRUaW1lKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5tYXgodGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIGF0IHRoZSBzcGVjaWZpZWQgdGltZS4gSWYgbm8gdGltZSBpcyBnaXZlbixcbiAgICAgKiBzdGFydCB0aGUgc291cmNlIG5vdy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdGFydGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc291cmNlID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzb3VyY2Uuc3RhcnQoXCIrMC41XCIpOyAvLyBzdGFydHMgdGhlIHNvdXJjZSAwLjUgc2Vjb25kcyBmcm9tIG5vd1xuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgbGV0IGNvbXB1dGVkVGltZSA9IGlzVW5kZWYodGltZSkgJiYgdGhpcy5fc3luY2VkID8gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzIDogdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbXB1dGVkVGltZSA9IHRoaXMuX2NsYW1wVG9DdXJyZW50VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAvLyBpZiBpdCdzIHN0YXJ0ZWQsIHN0b3AgaXQgYW5kIHJlc3RhcnQgaXRcbiAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQgJiYgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIHRpbWUgc2hvdWxkIGJlIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiB0aGUgcHJldmlvdXMgc3RhcnQgdGltZVxuICAgICAgICAgICAgYXNzZXJ0KEdUKGNvbXB1dGVkVGltZSwgdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSkudGltZSksIFwiU3RhcnQgdGltZSBtdXN0IGJlIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiBwcmV2aW91cyBzdGFydCB0aW1lXCIpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMubG9nKFwicmVzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5yZXN0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIG9mZnNldCB0aW1lIHRvIHRoZSBldmVudFxuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Lm9mZnNldCA9IHRoaXMudG9TZWNvbmRzKGRlZmF1bHRBcmcob2Zmc2V0LCAwKSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmR1cmF0aW9uID0gZHVyYXRpb24gPyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodCwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWQucHVzaChzY2hlZCk7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlIHRyYW5zcG9ydCBpcyBhbHJlYWR5IHN0YXJ0ZWRcbiAgICAgICAgICAgICAgICAvLyBhbmQgdGhlIHRpbWUgaXMgZ3JlYXRlciB0aGFuIHdoZXJlIHRoZSB0cmFuc3BvcnQgaXNcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKHRoaXMuaW1tZWRpYXRlKCkpID4gY29tcHV0ZWRUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0KHRoaXMubm93KCksIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0Q29udGV4dFJ1bm5pbmcodGhpcy5jb250ZXh0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChjb21wdXRlZFRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBzb3VyY2UgYXQgdGhlIHNwZWNpZmllZCB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLFxuICAgICAqIHN0b3AgdGhlIHNvdXJjZSBub3cuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHNvdXJjZSBzaG91bGQgYmUgc3RvcHBlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc291cmNlLnN0YXJ0KCk7XG4gICAgICogc291cmNlLnN0b3AoXCIrMC41XCIpOyAvLyBzdG9wcyB0aGUgc291cmNlIDAuNSBzZWNvbmRzIGZyb20gbm93XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGxldCBjb21wdXRlZFRpbWUgPSBpc1VuZGVmKHRpbWUpICYmIHRoaXMuX3N5bmNlZCA/IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyA6IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb21wdXRlZFRpbWUgPSB0aGlzLl9jbGFtcFRvQ3VycmVudFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiIHx8IGlzRGVmaW5lZCh0aGlzLl9zdGF0ZS5nZXROZXh0U3RhdGUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSkpKSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHRoaXMuX3N0b3AuYmluZCh0aGlzKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWQucHVzaChzY2hlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBzb3VyY2UuXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQgc28gdGhhdCBhbGwgc3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIGBzdGFydGAgYW5kIGBzdG9wYCBhcmUgc3luY2VkIHRvIHRoZSBUcmFuc3BvcnRUaW1lXG4gICAgICogaW5zdGVhZCBvZiB0aGUgQXVkaW9Db250ZXh0IHRpbWUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc3luYyB0aGUgc291cmNlIHNvIHRoYXQgaXQgcGxheXMgYmV0d2VlbiAwIGFuZCAwLjMgb24gdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lXG4gICAgICogb3NjLnN5bmMoKS5zdGFydCgwKS5zdG9wKDAuMyk7XG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICAgICAqIC8vIHNldCBpdCB0byBsb29wIG9uY2UgYSBzZWNvbmRcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wRW5kID0gMTtcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0ID0gKHRpbWUsIG9mZnNldCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRlRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQob2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdGVuIGZvciBzdGFydCBldmVudHMgd2hpY2ggbWF5IG9jY3VyIGluIHRoZSBtaWRkbGUgb2YgdGhlIHN5bmMnZWQgdGltZVxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGVFdmVudCAmJiBzdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBzdGF0ZUV2ZW50LnRpbWUgIT09IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBvZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0T2Zmc2V0ID0gb2Zmc2V0IC0gdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LmR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50LmR1cmF0aW9uKSAtIHN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC5vZmZzZXQpICsgc3RhcnRPZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gdGltZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuZ2V0U2Vjb25kc0F0VGltZShNYXRoLm1heCh0aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCAwKSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHNlY29uZHMpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcImxvb3BTdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJsb29wRW5kXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIHNvdXJjZSB0byB0aGUgVHJhbnNwb3J0LiBTZWUgU291cmNlLnN5bmNcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcImxvb3BFbmRcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwibG9vcFN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gY2xlYXIgYWxsIG9mIHRoZSBzY2hlZHVsZWQgaWRzXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZC5mb3JFYWNoKGlkID0+IHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoaWQpKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCgwKTtcbiAgICAgICAgLy8gc3RvcCBpdCBhbHNvXG4gICAgICAgIHRoaXMuX3N0b3AoMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub25zdG9wID0gbm9PcDtcbiAgICAgICAgdGhpcy51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Tb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL09uZVNob3RTb3VyY2VcIjtcbmltcG9ydCB7IEVRLCBHVEUsIExUIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgQnVmZmVyU291cmNlTm9kZS5cbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVCdWZmZXJTb3VyY2UgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUJ1ZmZlclNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVCdWZmZXJTb3VyY2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2UgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fc291cmNlXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGluZGljYXRvcnMgaWYgdGhlIHNvdXJjZSBoYXMgc3RhcnRlZC9zdG9wcGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3NvdXJjZVN0b3BwZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVCdWZmZXJTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NvdXJjZSwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9ICgpID0+IHRoaXMuX3N0b3BTb3VyY2UoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwbGF5YmFja1JhdGUgb2YgdGhlIGJ1ZmZlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3NvdXJjZS5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucGxheWJhY2tSYXRlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc2V0IHNvbWUgdmFsdWVzIGluaXRpYWxseVxuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcihvcHRpb25zLnVybCwgb3B0aW9ucy5vbmxvYWQsIG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMucHVzaCh0aGlzLl9zb3VyY2UpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdXJsOiBuZXcgVG9uZUF1ZGlvQnVmZmVyKCksXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVJbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcbiAgICB9XG4gICAgc2V0IGZhZGVJbih0KSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KHQpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJ2ZSBhcHBsaWVkIHRvIHRoZSBmYWRlcywgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG4gICAgICovXG4gICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VydmU7XG4gICAgfVxuICAgIHNldCBjdXJ2ZSh0KSB7XG4gICAgICAgIHRoaXMuX2N1cnZlID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGJ1ZmZlclxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqIEBwYXJhbSAgZ2FpbiAgVGhlIGdhaW4gdG8gcGxheSB0aGUgYnVmZmVyIGJhY2sgYXQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbiwgZ2FpbiA9IDEpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuYnVmZmVyLmxvYWRlZCwgXCJidWZmZXIgaXMgZWl0aGVyIG5vdCBzZXQgb3Igbm90IGxvYWRlZFwiKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIGFwcGx5IHRoZSBnYWluIGVudmVsb3BlXG4gICAgICAgIHRoaXMuX3N0YXJ0R2Fpbihjb21wdXRlZFRpbWUsIGdhaW4pO1xuICAgICAgICAvLyBpZiBpdCdzIGEgbG9vcCB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgdGhlIGxvb3BzdGFydCBwb2ludFxuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBvZmZzZXQgaXMgbm90IGxlc3MgdGhhbiAwXG4gICAgICAgIGxldCBjb21wdXRlZE9mZnNldCA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKG9mZnNldCksIDApO1xuICAgICAgICAvLyBzdGFydCB0aGUgYnVmZmVyIHNvdXJjZVxuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAvLyBtb2RpZnkgdGhlIG9mZnNldCBpZiBpdCdzIGdyZWF0ZXIgdGhhbiB0aGUgbG9vcCB0aW1lXG4gICAgICAgICAgICBjb25zdCBsb29wRW5kID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wRW5kKSB8fCB0aGlzLmJ1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IGxvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKHRoaXMubG9vcFN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnN0IGxvb3BEdXJhdGlvbiA9IGxvb3BFbmQgLSBsb29wU3RhcnQ7XG4gICAgICAgICAgICAvLyBtb3ZlIHRoZSBvZmZzZXQgYmFja1xuICAgICAgICAgICAgaWYgKEdURShjb21wdXRlZE9mZnNldCwgbG9vcEVuZCkpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlZE9mZnNldCA9ICgoY29tcHV0ZWRPZmZzZXQgLSBsb29wU3RhcnQpICUgbG9vcER1cmF0aW9uKSArIGxvb3BTdGFydDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHdoZW4gdGhlIG9mZnNldCBpcyB2ZXJ5IGNsb3NlIHRvIHRoZSBkdXJhdGlvbiwgc2V0IGl0IHRvIDBcbiAgICAgICAgICAgIGlmIChFUShjb21wdXRlZE9mZnNldCwgdGhpcy5idWZmZXIuZHVyYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZWRPZmZzZXQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHRoaXMuYnVmZmVyLmxvYWRlZCB3b3VsZCBoYXZlIHJldHVybiBmYWxzZSBpZiB0aGUgQXVkaW9CdWZmZXIgd2FzIHVuZGVmaW5lZFxuICAgICAgICB0aGlzLl9zb3VyY2UuYnVmZmVyID0gdGhpcy5idWZmZXIuZ2V0KCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wRW5kID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wRW5kKSB8fCB0aGlzLmJ1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgaWYgKExUKGNvbXB1dGVkT2Zmc2V0LCB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGEgZHVyYXRpb24gaXMgZ2l2ZW4sIHNjaGVkdWxlIGEgc3RvcFxuICAgICAgICBpZiAoaXNEZWZpbmVkKGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgbGV0IGNvbXB1dGVkRHVyID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGl0J3MgbmV2ZXIgbmVnYXRpdmVcbiAgICAgICAgICAgIGNvbXB1dGVkRHVyID0gTWF0aC5tYXgoY29tcHV0ZWREdXIsIDApO1xuICAgICAgICAgICAgdGhpcy5zdG9wKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3N0b3BTb3VyY2UodGltZSkge1xuICAgICAgICBpZiAoIXRoaXMuX3NvdXJjZVN0b3BwZWQgJiYgdGhpcy5fc291cmNlU3RhcnRlZCkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aGlzLnRvU2Vjb25kcyh0aW1lKSk7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIHN0YXJ0IGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyhsb29wU3RhcnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgZW5kIGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UubG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9zb3VyY2UubG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIGJlbG9uZ2luZyB0byB0aGUgcGxheWVyLlxuICAgICAqL1xuICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBzaG91bGQgbG9vcCBvbmNlIGl0J3Mgb3Zlci5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wID0gbG9vcDtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVN0YXJ0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc291cmNlLm9uZW5kZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVCdWZmZXJTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuLyoqXG4gKiBOb2lzZSBpcyBhIG5vaXNlIGdlbmVyYXRvci4gSXQgdXNlcyBsb29wZWQgbm9pc2UgYnVmZmVycyB0byBzYXZlIG9uIHBlcmZvcm1hbmNlLlxuICogTm9pc2Ugc3VwcG9ydHMgdGhlIG5vaXNlIHR5cGVzOiBcInBpbmtcIiwgXCJ3aGl0ZVwiLCBhbmQgXCJicm93blwiLiBSZWFkIG1vcmUgYWJvdXRcbiAqIGNvbG9ycyBvZiBub2lzZSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db2xvcnNfb2Zfbm9pc2UpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBpbml0aWFsaXplIHRoZSBub2lzZSBhbmQgc3RhcnRcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoXCJwaW5rXCIpLnN0YXJ0KCk7XG4gKiAvLyBtYWtlIGFuIGF1dG9maWx0ZXIgdG8gc2hhcGUgdGhlIG5vaXNlXG4gKiBjb25zdCBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcih7XG4gKiBcdGZyZXF1ZW5jeTogXCI4blwiLFxuICogXHRiYXNlRnJlcXVlbmN5OiAyMDAsXG4gKiBcdG9jdGF2ZXM6IDhcbiAqIH0pLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gY29ubmVjdCB0aGUgbm9pc2VcbiAqIG5vaXNlLmNvbm5lY3QoYXV0b0ZpbHRlcik7XG4gKiAvLyBzdGFydCB0aGUgYXV0b2ZpbHRlciBMRk9cbiAqIGF1dG9GaWx0ZXIuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE5vaXNlIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTm9pc2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByaXZhdGUgcmVmZXJlbmNlIHRvIHRoZSBzb3VyY2VcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHR5cGU6IFwid2hpdGVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBub2lzZS4gQ2FuIGJlIFwid2hpdGVcIiwgXCJicm93blwiLCBvciBcInBpbmtcIi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBub2lzZS50eXBlID0gXCJicm93blwiO1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBhc3NlcnQodHlwZSBpbiBfbm9pc2VCdWZmZXJzLCBcIk5vaXNlOiBpbnZhbGlkIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlICE9PSB0eXBlKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgcGxheWluZywgc3RvcCBhbmQgcmVzdGFydCBpdFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKG5vdyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQobm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbm9pc2UuIEFmZmVjdHNcbiAgICAgKiB0aGUgXCJmcmVxdWVuY3lcIiBvZiB0aGUgbm9pc2UuXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5wbGF5YmFja1JhdGUudmFsdWUgPSByYXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IF9ub2lzZUJ1ZmZlcnNbdGhpcy5fdHlwZV07XG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgIHVybDogYnVmZmVyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZUluOiB0aGlzLl9mYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9mYWRlT3V0LFxuICAgICAgICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgICAgICAgIG9uZW5kZWQ6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiB0aGlzLl9wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQodGhpcy50b1NlY29uZHModGltZSksIE1hdGgucmFuZG9tKCkgKiAoYnVmZmVyLmR1cmF0aW9uIC0gMC4wMDEpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogaW50ZXJuYWwgc3RvcCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVJbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcbiAgICB9XG4gICAgc2V0IGZhZGVJbih0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IHRpbWU7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5mYWRlSW4gPSB0aGlzLl9mYWRlSW47XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQodGltZSkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gdGltZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmZhZGVPdXQgPSB0aGlzLl9mYWRlT3V0O1xuICAgICAgICB9XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgLy8gVE9ETyBjb3VsZCBiZSBvcHRpbWl6ZWQgYnkgY2FuY2VsbGluZyB0aGUgYnVmZmVyIHNvdXJjZSAnc3RvcCdcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUSEUgTk9JU0UgQlVGRkVSU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTm9pc2UgYnVmZmVyIHN0YXRzXG5jb25zdCBCVUZGRVJfTEVOR1RIID0gNDQxMDAgKiA1O1xuY29uc3QgTlVNX0NIQU5ORUxTID0gMjtcbi8qKlxuICogQ2FjaGUgdGhlIG5vaXNlIGJ1ZmZlcnNcbiAqL1xuY29uc3QgX25vaXNlQ2FjaGUgPSB7XG4gICAgYnJvd246IG51bGwsXG4gICAgcGluazogbnVsbCxcbiAgICB3aGl0ZTogbnVsbCxcbn07XG4vKipcbiAqIFRoZSBub2lzZSBhcnJheXMuIEdlbmVyYXRlZCBvbiBpbml0aWFsaXphdGlvbi5cbiAqIGJvcnJvd2VkIGhlYXZpbHkgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vemFjaGFyeWRlbnRvbi9ub2lzZS5qc1xuICogKGMpIDIwMTMgWmFjaCBEZW50b24gKE1JVClcbiAqL1xuY29uc3QgX25vaXNlQnVmZmVycyA9IHtcbiAgICBnZXQgYnJvd24oKSB7XG4gICAgICAgIGlmICghX25vaXNlQ2FjaGUuYnJvd24pIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RPdXQgPSAwLjA7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCVUZGRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2hpdGUgPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gPSAobGFzdE91dCArICgwLjAyICogd2hpdGUpKSAvIDEuMDI7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RPdXQgPSBjaGFubmVsW2ldO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldICo9IDMuNTsgLy8gKHJvdWdobHkpIGNvbXBlbnNhdGUgZm9yIGdhaW5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfbm9pc2VDYWNoZS5icm93biA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUuYnJvd247XG4gICAgfSxcbiAgICBnZXQgcGluaygpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS5waW5rKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgTlVNX0NIQU5ORUxTOyBjaGFubmVsTnVtKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IEZsb2F0MzJBcnJheShCVUZGRVJfTEVOR1RIKTtcbiAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuICAgICAgICAgICAgICAgIGxldCBiMCwgYjEsIGIyLCBiMywgYjQsIGI1LCBiNjtcbiAgICAgICAgICAgICAgICBiMCA9IGIxID0gYjIgPSBiMyA9IGI0ID0gYjUgPSBiNiA9IDAuMDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgYjAgPSAwLjk5ODg2ICogYjAgKyB3aGl0ZSAqIDAuMDU1NTE3OTtcbiAgICAgICAgICAgICAgICAgICAgYjEgPSAwLjk5MzMyICogYjEgKyB3aGl0ZSAqIDAuMDc1MDc1OTtcbiAgICAgICAgICAgICAgICAgICAgYjIgPSAwLjk2OTAwICogYjIgKyB3aGl0ZSAqIDAuMTUzODUyMDtcbiAgICAgICAgICAgICAgICAgICAgYjMgPSAwLjg2NjUwICogYjMgKyB3aGl0ZSAqIDAuMzEwNDg1NjtcbiAgICAgICAgICAgICAgICAgICAgYjQgPSAwLjU1MDAwICogYjQgKyB3aGl0ZSAqIDAuNTMyOTUyMjtcbiAgICAgICAgICAgICAgICAgICAgYjUgPSAtMC43NjE2ICogYjUgLSB3aGl0ZSAqIDAuMDE2ODk4MDtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IGIwICsgYjEgKyBiMiArIGIzICsgYjQgKyBiNSArIGI2ICsgd2hpdGUgKiAwLjUzNjI7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gKj0gMC4xMTsgLy8gKHJvdWdobHkpIGNvbXBlbnNhdGUgZm9yIGdhaW5cbiAgICAgICAgICAgICAgICAgICAgYjYgPSB3aGl0ZSAqIDAuMTE1OTI2O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLnBpbmsgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCkuZnJvbUFycmF5KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9ub2lzZUNhY2hlLnBpbms7XG4gICAgfSxcbiAgICBnZXQgd2hpdGUoKSB7XG4gICAgICAgIGlmICghX25vaXNlQ2FjaGUud2hpdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCVUZGRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfbm9pc2VDYWNoZS53aGl0ZSA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUud2hpdGU7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ob2lzZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGNvbm5lY3QsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFVzZXJNZWRpYSB1c2VzIE1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgdG8gb3BlbiB1cCBhbmQgZXh0ZXJuYWwgbWljcm9waG9uZSBvciBhdWRpbyBpbnB1dC5cbiAqIENoZWNrIFtNZWRpYURldmljZXMgQVBJIFN1cHBvcnRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9NZWRpYURldmljZXMvZ2V0VXNlck1lZGlhKVxuICogdG8gc2VlIHdoaWNoIGJyb3dzZXJzIGFyZSBzdXBwb3J0ZWQuIEFjY2VzcyB0byBhbiBleHRlcm5hbCBpbnB1dFxuICogaXMgbGltaXRlZCB0byBzZWN1cmUgKEhUVFBTKSBjb25uZWN0aW9ucy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXRlciA9IG5ldyBUb25lLk1ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKS5jb25uZWN0KG1ldGVyKTtcbiAqIG1pYy5vcGVuKCkudGhlbigoKSA9PiB7XG4gKiBcdC8vIHByb21pc2UgcmVzb2x2ZXMgd2hlbiBpbnB1dCBpcyBhdmFpbGFibGVcbiAqIFx0Y29uc29sZS5sb2coXCJtaWMgb3BlblwiKTtcbiAqIFx0Ly8gcHJpbnQgdGhlIGluY29taW5nIG1pYyBsZXZlbHMgaW4gZGVjaWJlbHNcbiAqIFx0c2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2cobWV0ZXIuZ2V0VmFsdWUoKSksIDEwMCk7XG4gKiB9KS5jYXRjaChlID0+IHtcbiAqIFx0Ly8gcHJvbWlzZSBpcyByZWplY3RlZCB3aGVuIHRoZSB1c2VyIGRvZXNuJ3QgaGF2ZSBvciBhbGxvdyBtaWMgYWNjZXNzXG4gKiBcdGNvbnNvbGUubG9nKFwibWljIG5vdCBvcGVuXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VyTWVkaWEgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVXNlck1lZGlhLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVXNlck1lZGlhXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhVc2VyTWVkaWEuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVuIHRoZSBtZWRpYSBzdHJlYW0uIElmIGEgc3RyaW5nIGlzIHBhc3NlZCBpbiwgaXQgaXMgYXNzdW1lZFxuICAgICAqIHRvIGJlIHRoZSBsYWJlbCBvciBpZCBvZiB0aGUgc3RyZWFtLCBpZiBhIG51bWJlciBpcyBwYXNzZWQgaW4sXG4gICAgICogaXQgaXMgdGhlIGlucHV0IG51bWJlciBvZiB0aGUgc3RyZWFtLlxuICAgICAqIEBwYXJhbSAgbGFiZWxPcklkIFRoZSBsYWJlbCBvciBpZCBvZiB0aGUgYXVkaW8gaW5wdXQgbWVkaWEgZGV2aWNlLlxuICAgICAqICAgICAgICAgICAgICAgICAgIFdpdGggbm8gYXJndW1lbnQsIHRoZSBkZWZhdWx0IHN0cmVhbSBpcyBvcGVuZWQuXG4gICAgICogQHJldHVybiBUaGUgcHJvbWlzZSBpcyByZXNvbHZlZCB3aGVuIHRoZSBzdHJlYW0gaXMgb3Blbi5cbiAgICAgKi9cbiAgICBvcGVuKGxhYmVsT3JJZCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KFVzZXJNZWRpYS5zdXBwb3J0ZWQsIFwiVXNlck1lZGlhIGlzIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgICAgICAvLyBjbG9zZSB0aGUgcHJldmlvdXMgc3RyZWFtXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBkZXZpY2VzID0geWllbGQgVXNlck1lZGlhLmVudW1lcmF0ZURldmljZXMoKTtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihsYWJlbE9ySWQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlc1tsYWJlbE9ySWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlcy5maW5kKChkZXZpY2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZS5sYWJlbCA9PT0gbGFiZWxPcklkIHx8IGRldmljZS5kZXZpY2VJZCA9PT0gbGFiZWxPcklkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8vIGRpZG4ndCBmaW5kIGEgbWF0Y2hpbmcgZGV2aWNlXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kZXZpY2UgJiYgZGV2aWNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2RldmljZSA9IGRldmljZXNbMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFzc2VydChpc0RlZmluZWQodGhpcy5fZGV2aWNlKSwgYE5vIG1hdGNoaW5nIGRldmljZSAke2xhYmVsT3JJZH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRvIGdldFVzZXJNZWRpYVxuICAgICAgICAgICAgY29uc3QgY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICAgICAgZWNob0NhbmNlbGxhdGlvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlLFxuICAgICAgICAgICAgICAgICAgICBub2lzZVN1cHByZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbW96Tm9pc2VTdXBwcmVzc2lvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgY29uc3RyYWludHMuYXVkaW8uZGV2aWNlSWQgPSB0aGlzLl9kZXZpY2UuZGV2aWNlSWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSB5aWVsZCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cyk7XG4gICAgICAgICAgICAvLyBzdGFydCBhIG5ldyBzb3VyY2Ugb25seSBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGNsb3NlZFxuICAgICAgICAgICAgaWYgKCF0aGlzLl9zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgLy8gV3JhcCBhIE1lZGlhU3RyZWFtU291cmNlTm9kZSBhcm91bmQgdGhlIGxpdmUgaW5wdXQgc3RyZWFtLlxuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIENvbm5lY3QgdGhlIE1lZGlhU3RyZWFtU291cmNlTm9kZSB0byBhIGdhdGUgZ2FpbiBub2RlXG4gICAgICAgICAgICAgICAgY29ubmVjdChtZWRpYVN0cmVhbU5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IG1lZGlhU3RyZWFtTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIG1lZGlhIHN0cmVhbVxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICBpZiAodGhpcy5fc3RyZWFtICYmIHRoaXMuX21lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLl9zdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvbGQgbWVkaWEgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9kZXZpY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aXRoIHRoZSBsaXN0IG9mIGF1ZGlvIGlucHV0IGRldmljZXMgYXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4gVGhlIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aXRoIHRoZSBkZXZpY2VzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlVzZXJNZWRpYS5lbnVtZXJhdGVEZXZpY2VzKCkudGhlbigoZGV2aWNlcykgPT4ge1xuICAgICAqIFx0Ly8gcHJpbnQgdGhlIGRldmljZSBsYWJlbHNcbiAgICAgKiBcdGNvbnNvbGUubG9nKGRldmljZXMubWFwKGRldmljZSA9PiBkZXZpY2UubGFiZWwpKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBzdGF0aWMgZW51bWVyYXRlRGV2aWNlcygpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbERldmljZXMgPSB5aWVsZCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKTtcbiAgICAgICAgICAgIHJldHVybiBhbGxEZXZpY2VzLmZpbHRlcihkZXZpY2UgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXZpY2Uua2luZCA9PT0gXCJhdWRpb2lucHV0XCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIFwic3RhcnRlZFwiIHdoZW4gdGhlIG1pY3JvcGhvbmUgaXMgb3BlblxuICAgICAqIGFuZCBcInN0b3BwZWRcIiB3aGVuIHRoZSBtaWMgaXMgY2xvc2VkLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0cmVhbSAmJiB0aGlzLl9zdHJlYW0uYWN0aXZlID8gXCJzdGFydGVkXCIgOiBcInN0b3BwZWRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBpZGVudGlmaWVyIGZvciB0aGUgcmVwcmVzZW50ZWQgZGV2aWNlIHRoYXQgaXNcbiAgICAgKiBwZXJzaXN0ZWQgYWNyb3NzIHNlc3Npb25zLiBJdCBpcyB1bi1ndWVzc2FibGUgYnkgb3RoZXIgYXBwbGljYXRpb25zIGFuZFxuICAgICAqIHVuaXF1ZSB0byB0aGUgb3JpZ2luIG9mIHRoZSBjYWxsaW5nIGFwcGxpY2F0aW9uLiBJdCBpcyByZXNldCB3aGVuIHRoZVxuICAgICAqIHVzZXIgY2xlYXJzIGNvb2tpZXMgKGZvciBQcml2YXRlIEJyb3dzaW5nLCBhIGRpZmZlcmVudCBpZGVudGlmaWVyIGlzXG4gICAgICogdXNlZCB0aGF0IGlzIG5vdCBwZXJzaXN0ZWQgYWNyb3NzIHNlc3Npb25zKS4gUmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGVcbiAgICAgKiBkZXZpY2UgaXMgbm90IG9wZW4uXG4gICAgICovXG4gICAgZ2V0IGRldmljZUlkKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmRldmljZUlkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZ3JvdXAgaWRlbnRpZmllci4gVHdvIGRldmljZXMgaGF2ZSB0aGVcbiAgICAgKiBzYW1lIGdyb3VwIGlkZW50aWZpZXIgaWYgdGhleSBiZWxvbmcgdG8gdGhlIHNhbWUgcGh5c2ljYWwgZGV2aWNlLlxuICAgICAqIFJldHVybnMgbnVsbCAgd2hlbiB0aGUgZGV2aWNlIGlzIG5vdCBvcGVuLlxuICAgICAqL1xuICAgIGdldCBncm91cElkKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmdyb3VwSWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBsYWJlbCBkZXNjcmliaW5nIHRoaXMgZGV2aWNlIChmb3IgZXhhbXBsZSBcIkJ1aWx0LWluIE1pY3JvcGhvbmVcIikuXG4gICAgICogUmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGUgZGV2aWNlIGlzIG5vdCBvcGVuIG9yIGxhYmVsIGlzIG5vdCBhdmFpbGFibGVcbiAgICAgKiBiZWNhdXNlIG9mIHBlcm1pc3Npb25zLlxuICAgICAqL1xuICAgIGdldCBsYWJlbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldmljZS5sYWJlbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG4gICAgICogbWljLm9wZW4oKS50aGVuKCgpID0+IHtcbiAgICAgKiBcdC8vIHByb21pc2UgcmVzb2x2ZXMgd2hlbiBpbnB1dCBpcyBhdmFpbGFibGVcbiAgICAgKiB9KTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBtaWMubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBnZXRVc2VyTWVkaWEgaXMgc3VwcG9ydGVkIGJ5IHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc3VwcG9ydGVkKCkge1xuICAgICAgICByZXR1cm4gaXNEZWZpbmVkKG5hdmlnYXRvci5tZWRpYURldmljZXMpICYmXG4gICAgICAgICAgICBpc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVVzZXJNZWRpYS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuLyoqXG4gKiBSZW5kZXIgYSBzZWdtZW50IG9mIHRoZSBvc2NpbGxhdG9yIHRvIGFuIG9mZmxpbmUgY29udGV4dCBhbmQgcmV0dXJuIHRoZSByZXN1bHRzIGFzIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVdhdmVmb3JtKGluc3RhbmNlLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBkdXJhdGlvbiA9IGxlbmd0aCAvIGluc3RhbmNlLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dCgxLCBkdXJhdGlvbiwgaW5zdGFuY2UuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgY2xvbmUgPSBuZXcgaW5zdGFuY2UuY29uc3RydWN0b3IoT2JqZWN0LmFzc2lnbihpbnN0YW5jZS5nZXQoKSwge1xuICAgICAgICAgICAgLy8gc2hvdWxkIGRvIDIgaXRlcmF0aW9uc1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAyIC8gZHVyYXRpb24sXG4gICAgICAgICAgICAvLyB6ZXJvIG91dCB0aGUgZGV0dW5lXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBjb250ZXh0XG4gICAgICAgIH0pKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgIGNsb25lLnN0YXJ0KDApO1xuICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICByZXR1cm4gYnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgIH0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T3NjaWxsYXRvckludGVyZmFjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9PbmVTaG90U291cmNlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgZmlyZS1hbmQtZm9yZ2V0IE9zY2lsbGF0b3JOb2RlLlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byByZXNjaGVkdWxlIHRoZSBzdG9wIG1ldGhvZC5cbiAqICoqKltbT3NjaWxsYXRvcl1dIGlzIGJldHRlciBmb3IgbW9zdCB1c2UtY2FzZXMqKipcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVPc2NpbGxhdG9yTm9kZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lT3NjaWxsYXRvck5vZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3NjaWxsYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fb3NjaWxsYXRvcl07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lT3NjaWxsYXRvck5vZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fb3NjaWxsYXRvci5kZXR1bmUsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPbmVTaG90U291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgb3NjaWxsYXRvciBub2RlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0R2Fpbihjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyBhbiBhcmJpdHJhcnkgY3VzdG9tIHBlcmlvZGljIHdhdmVmb3JtIGdpdmVuIGEgUGVyaW9kaWNXYXZlLlxuICAgICAqIEBwYXJhbSAgcGVyaW9kaWNXYXZlIFBlcmlvZGljV2F2ZSBzaG91bGQgYmUgY3JlYXRlZCB3aXRoIGNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlXG4gICAgICovXG4gICAgc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZS4gRWl0aGVyICdzaW5lJywgJ3Nhd3Rvb3RoJywgJ3NxdWFyZScsIG9yICd0cmlhbmdsZSdcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lT3NjaWxsYXRvck5vZGUuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBkZWVwRXF1YWxzLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVPc2NpbGxhdG9yTm9kZSB9IGZyb20gXCIuL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBPc2NpbGxhdG9yIHN1cHBvcnRzIGEgbnVtYmVyIG9mIGZlYXR1cmVzIGluY2x1ZGluZ1xuICogcGhhc2Ugcm90YXRpb24sIG11bHRpcGxlIG9zY2lsbGF0b3IgdHlwZXMgKHNlZSBPc2NpbGxhdG9yLnR5cGUpLFxuICogYW5kIFRyYW5zcG9ydCBzeW5jaW5nIChzZWUgT3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5KS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gbWFrZSBhbmQgc3RhcnQgYSA0NDBoeiBzaW5lIHRvbmVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNpbmVcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbWFpbiBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbnVsbDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZXR1bmVcIik7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gb3B0aW9ucy5wYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3B0aW9ucy5wYXJ0aWFsQ291bnQ7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIGlmIChvcHRpb25zLnBhcnRpYWxDb3VudCAmJiBvcHRpb25zLnR5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0aGlzLmJhc2VUeXBlICsgb3B0aW9ucy5wYXJ0aWFsQ291bnQudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICBwYXJ0aWFsQ291bnQ6IDAsXG4gICAgICAgICAgICBwYXJ0aWFsczogW10sXG4gICAgICAgICAgICBwaGFzZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gbmV3IG9zY2lsbGF0b3Igd2l0aCBwcmV2aW91cyB2YWx1ZXNcbiAgICAgICAgY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lT3NjaWxsYXRvck5vZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb25lbmRlZDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gb3NjaWxsYXRvcjtcbiAgICAgICAgaWYgKHRoaXMuX3dhdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb25uZWN0IHRoZSBjb250cm9sIHNpZ25hbCB0byB0aGUgb3NjaWxsYXRvciBmcmVxdWVuY3kgJiBkZXR1bmVcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5kZXR1bmUpO1xuICAgICAgICAvLyBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgb3NjaWxsYXRvci4gRG9lcyBub3Qgc3RvcCB0aGUgb3NjaWxsYXRvciwgYnV0IGluc3RlYWRcbiAgICAgKiBqdXN0IGNhbmNlbHMgYW55IHNjaGVkdWxlZCAnc3RvcCcgZnJvbSBiZWluZyBpbnZva2VkLlxuICAgICAqL1xuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwicmVzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jYW5jZWxTdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzaWduYWwgdG8gdGhlIFRyYW5zcG9ydCdzIGJwbS4gQW55IGNoYW5nZXMgdG8gdGhlIHRyYW5zcG9ydHMgYnBtLFxuICAgICAqIHdpbGwgYWxzbyBhZmZlY3QgdGhlIG9zY2lsbGF0b3JzIGZyZXF1ZW5jeS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBvc2MuZnJlcXVlbmN5LnZhbHVlID0gNDQwO1xuICAgICAqIC8vIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSBicG0gYW5kIHRoZSBmcmVxdWVuY3kgd2lsbCBiZSBtYWludGFpbmVkXG4gICAgICogb3NjLnN5bmNGcmVxdWVuY3koKTtcbiAgICAgKiAvLyBkb3VibGUgdGhlIHRlbXBvXG4gICAgICogVG9uZS5UcmFuc3BvcnQuYnBtLnZhbHVlICo9IDI7XG4gICAgICogLy8gdGhlIGZyZXF1ZW5jeSBvZiB0aGUgb3NjaWxsYXRvciBpcyBkb3VibGVkIHRvIDg4MFxuICAgICAqL1xuICAgIHN5bmNGcmVxdWVuY3koKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIG9zY2lsbGF0b3IncyBmcmVxdWVuY3kgZnJvbSB0aGUgVHJhbnNwb3J0LlxuICAgICAqIFNlZSBPc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3lcbiAgICAgKi9cbiAgICB1bnN5bmNGcmVxdWVuY3koKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQudW5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGNhY2hlZCBwZXJpb2RpYyB3YXZlLiBBdm9pZHMgaGF2aW5nIHRvIHJlY29tcHV0ZVxuICAgICAqIHRoZSBvc2NpbGxhdG9yIHZhbHVlcyB3aGVuIHRoZXkgaGF2ZSBhbHJlYWR5IGJlZW4gY29tcHV0ZWRcbiAgICAgKiB3aXRoIHRoZSBzYW1lIHZhbHVlcy5cbiAgICAgKi9cbiAgICBfZ2V0Q2FjaGVkUGVyaW9kaWNXYXZlKCkge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgY29uc3Qgb3NjUHJvcHMgPSBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5maW5kKGRlc2NyaXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb24ucGhhc2UgPT09IHRoaXMuX3BoYXNlICYmXG4gICAgICAgICAgICAgICAgICAgIGRlZXBFcXVhbHMoZGVzY3JpcHRpb24ucGFydGlhbHMsIHRoaXMuX3BhcnRpYWxzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIG9zY1Byb3BzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgb3NjUHJvcHMgPSBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5maW5kKGRlc2NyaXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb24udHlwZSA9PT0gdGhpcy5fdHlwZSAmJlxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5waGFzZSA9PT0gdGhpcy5fcGhhc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9zY1Byb3BzID8gb3NjUHJvcHMucGFydGlhbENvdW50IDogdGhpcy5fcGFydGlhbENvdW50O1xuICAgICAgICAgICAgcmV0dXJuIG9zY1Byb3BzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgY29uc3QgaXNCYXNpY1R5cGUgPSBbXCJzaW5lXCIsIFwic3F1YXJlXCIsIFwic2F3dG9vdGhcIiwgXCJ0cmlhbmdsZVwiXS5pbmRleE9mKHR5cGUpICE9PSAtMTtcbiAgICAgICAgaWYgKHRoaXMuX3BoYXNlID09PSAwICYmIGlzQmFzaWNUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLl93YXZlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gMDtcbiAgICAgICAgICAgIC8vIGp1c3QgZ28gd2l0aCB0aGUgYmFzaWMgYXBwcm9hY2hcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSB0ZXN0ZWQgdGhhdCBpdCdzIGEgYmFzaWMgdHlwZVxuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBmaXJzdCBjaGVjayBpZiB0aGUgdmFsdWUgaXMgY2FjaGVkXG4gICAgICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2dldENhY2hlZFBlcmlvZGljV2F2ZSgpO1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChjYWNoZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHBhcnRpYWxzLCB3YXZlIH0gPSBjYWNoZTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gd2F2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtyZWFsLCBpbWFnXSA9IHRoaXMuX2dldFJlYWxJbWFnaW5hcnkodHlwZSwgdGhpcy5fcGhhc2UpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBlcmlvZGljV2F2ZSA9IHRoaXMuY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2F2ZSA9IHBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBjYWNoZVxuICAgICAgICAgICAgICAgIE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpbWFnLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQ6IHRoaXMuX3BhcnRpYWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbHM6IHRoaXMuX3BhcnRpYWxzLFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogdGhpcy5fcGhhc2UsXG4gICAgICAgICAgICAgICAgICAgIHJlYWwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgIHdhdmU6IHRoaXMuX3dhdmUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmxlbmd0aCA+IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlLnJlcGxhY2UodGhpcy5wYXJ0aWFsQ291bnQudG9TdHJpbmcoKSwgXCJcIik7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICBpZiAodGhpcy5wYXJ0aWFsQ291bnQgJiYgdGhpcy5fdHlwZSAhPT0gXCJjdXN0b21cIiAmJiBiYXNlVHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGUgKyB0aGlzLnBhcnRpYWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocCkge1xuICAgICAgICBhc3NlcnRSYW5nZShwLCAwKTtcbiAgICAgICAgbGV0IHR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICBjb25zdCBwYXJ0aWFsID0gL14oc2luZXx0cmlhbmdsZXxzcXVhcmV8c2F3dG9vdGgpKFxcZCspJC8uZXhlYyh0aGlzLl90eXBlKTtcbiAgICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgICAgIHR5cGUgPSBwYXJ0aWFsWzFdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl90eXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBpZiAocCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlICsgcC50b1N0cmluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gZXh0ZW5kIG9yIHNob3J0ZW4gdGhlIHBhcnRpYWxzIGFycmF5XG4gICAgICAgICAgICBjb25zdCBmdWxsUGFydGlhbHMgPSBuZXcgRmxvYXQzMkFycmF5KHApO1xuICAgICAgICAgICAgLy8gY29weSBvdmVyIHRoZSBwYXJ0aWFscyBhcnJheVxuICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMuZm9yRWFjaCgodiwgaSkgPT4gZnVsbFBhcnRpYWxzW2ldID0gdik7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IEFycmF5LmZyb20oZnVsbFBhcnRpYWxzKTtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcmVhbCBhbmQgaW1hZ2luYXJ5IGNvbXBvbmVudHMgYmFzZWRcbiAgICAgKiBvbiB0aGUgb3NjaWxsYXRvciB0eXBlLlxuICAgICAqIEByZXR1cm5zIFtyZWFsOiBGbG9hdDMyQXJyYXksIGltYWdpbmFyeTogRmxvYXQzMkFycmF5XVxuICAgICAqL1xuICAgIF9nZXRSZWFsSW1hZ2luYXJ5KHR5cGUsIHBoYXNlKSB7XG4gICAgICAgIGNvbnN0IGZmdFNpemUgPSA0MDk2O1xuICAgICAgICBsZXQgcGVyaW9kaWNXYXZlU2l6ZSA9IGZmdFNpemUgLyAyO1xuICAgICAgICBjb25zdCByZWFsID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcbiAgICAgICAgY29uc3QgaW1hZyA9IG5ldyBGbG9hdDMyQXJyYXkocGVyaW9kaWNXYXZlU2l6ZSk7XG4gICAgICAgIGxldCBwYXJ0aWFsQ291bnQgPSAxO1xuICAgICAgICBpZiAodHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoICsgMTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aDtcbiAgICAgICAgICAgIHBlcmlvZGljV2F2ZVNpemUgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICAvLyBpZiB0aGUgcGFydGlhbCBjb3VudCBpcyAwLCBkb24ndCBib3RoZXIgZG9pbmcgYW55IGNvbXB1dGF0aW9uXG4gICAgICAgICAgICBpZiAodGhpcy5fcGFydGlhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtyZWFsLCBpbWFnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHR5cGUpO1xuICAgICAgICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSBwYXJzZUludChwYXJ0aWFsWzJdLCAxMCkgKyAxO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHBhcnNlSW50KHBhcnRpYWxbMl0sIDEwKTtcbiAgICAgICAgICAgICAgICB0eXBlID0gcGFydGlhbFsxXTtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSBNYXRoLm1heChwYXJ0aWFsQ291bnQsIDIpO1xuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZVNpemUgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBuID0gMTsgbiA8IHBlcmlvZGljV2F2ZVNpemU7ICsrbikge1xuICAgICAgICAgICAgY29uc3QgcGlGYWN0b3IgPSAyIC8gKG4gKiBNYXRoLlBJKTtcbiAgICAgICAgICAgIGxldCBiO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNpbmVcIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IChuIDw9IHBhcnRpYWxDb3VudCkgPyAxIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNxdWFyZVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gKG4gJiAxKSA/IDIgKiBwaUZhY3RvciA6IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzYXd0b290aFwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gcGlGYWN0b3IgKiAoKG4gJiAxKSA/IDEgOiAtMSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ0cmlhbmdsZVwiOlxuICAgICAgICAgICAgICAgICAgICBpZiAobiAmIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSAyICogKHBpRmFjdG9yICogcGlGYWN0b3IpICogKCgoKG4gLSAxKSA+PiAxKSAmIDEpID8gLTEgOiAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IHRoaXMuX3BhcnRpYWxzW24gLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9zY2lsbGF0b3I6IGludmFsaWQgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmVhbFtuXSA9IC1iICogTWF0aC5zaW4ocGhhc2UgKiBuKTtcbiAgICAgICAgICAgICAgICBpbWFnW25dID0gYiAqIE1hdGguY29zKHBoYXNlICogbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWFsW25dID0gMDtcbiAgICAgICAgICAgICAgICBpbWFnW25dID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3JlYWwsIGltYWddO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb21wdXRlIHRoZSBpbnZlcnNlIEZGVCBmb3IgYSBnaXZlbiBwaGFzZS5cbiAgICAgKi9cbiAgICBfaW52ZXJzZUZGVChyZWFsLCBpbWFnLCBwaGFzZSkge1xuICAgICAgICBsZXQgc3VtID0gMDtcbiAgICAgICAgY29uc3QgbGVuID0gcmVhbC5sZW5ndGg7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHN1bSArPSByZWFsW2ldICogTWF0aC5jb3MoaSAqIHBoYXNlKSArIGltYWdbaV0gKiBNYXRoLnNpbihpICogcGhhc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdW07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzdG9wcGVkLlxuICAgICAqIEUuZy4gYSBcInNpbmVcIiBvc2NpbGxhdG9yIHdpdGggcGhhc2UgPSA5MCB3b3VsZCByZXR1cm4gYW4gaW5pdGlhbCB2YWx1ZSBvZiAtMS5cbiAgICAgKi9cbiAgICBnZXRJbml0aWFsVmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IFtyZWFsLCBpbWFnXSA9IHRoaXMuX2dldFJlYWxJbWFnaW5hcnkodGhpcy5fdHlwZSwgMCk7XG4gICAgICAgIGxldCBtYXhWYWx1ZSA9IDA7XG4gICAgICAgIGNvbnN0IHR3b1BpID0gTWF0aC5QSSAqIDI7XG4gICAgICAgIGNvbnN0IHRlc3RQb3NpdGlvbnMgPSAzMjtcbiAgICAgICAgLy8gY2hlY2sgZm9yIHBlYWtzIGluIDE2IHBsYWNlc1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlc3RQb3NpdGlvbnM7IGkrKykge1xuICAgICAgICAgICAgbWF4VmFsdWUgPSBNYXRoLm1heCh0aGlzLl9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIChpIC8gdGVzdFBvc2l0aW9ucykgKiB0d29QaSksIG1heFZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xhbXAoLXRoaXMuX2ludmVyc2VGRlQocmVhbCwgaW1hZywgdGhpcy5fcGhhc2UpIC8gbWF4VmFsdWUsIC0xLCAxKTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydGlhbHMuc2xpY2UoMCwgdGhpcy5wYXJ0aWFsQ291bnQpO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImN1c3RvbVwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlICogKDE4MCAvIE1hdGguUEkpO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZSAqIE1hdGguUEkgLyAxODA7XG4gICAgICAgIC8vIHJlc2V0IHRoZSB0eXBlXG4gICAgICAgIHRoaXMudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3dhdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIENhY2hlIHRoZSBwZXJpb2RpYyB3YXZlcyB0byBhdm9pZCBoYXZpbmcgdG8gcmVkbyBjb21wdXRhdGlvbnNcbiAqL1xuT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUgPSBbXTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBjb25uZWN0U2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIEEgc2lnbmFsIG9wZXJhdG9yIGhhcyBhbiBpbnB1dCBhbmQgb3V0cHV0IGFuZCBtb2RpZmllcyB0aGUgc2lnbmFsLlxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsT3BlcmF0b3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWxPcGVyYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNvbnRleHRcIl0pKSk7XG4gICAgfVxuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2lnbmFsT3BlcmF0b3IuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Z1bmN0aW9uIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBXcmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbyBBUElcbiAqIFtXYXZlU2hhcGVyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtd2F2ZXNoYXBlcm5vZGUtaW50ZXJmYWNlKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gbXVsdGlwbHkgdGhlIG91dHB1dCBvZiB0aGUgc2lnbmFsIGJ5IDIgdXNpbmcgdGhlIHdhdmVzaGFwZXIncyBmdW5jdGlvblxuICogY29uc3QgdGltZXNUd28gPSBuZXcgVG9uZS5XYXZlU2hhcGVyKCh2YWwpID0+IHZhbCAqIDIsIDIwNDgpLmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoNDQwKS5jb25uZWN0KHRpbWVzVHdvKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFdhdmVTaGFwZXIgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZVNoYXBlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1hcHBpbmdcIiwgXCJsZW5ndGhcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiV2F2ZVNoYXBlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHdhdmVzaGFwZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2hhcGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB0byB0aGUgd2F2ZXNoYXBlciBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3NoYXBlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgZnJvbSB0aGUgd2F2ZXNoYXBlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3NoYXBlcjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVTaGFwZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtYXBwaW5nXCIsIFwibGVuZ3RoXCJdKTtcbiAgICAgICAgaWYgKGlzQXJyYXkob3B0aW9ucy5tYXBwaW5nKSB8fCBvcHRpb25zLm1hcHBpbmcgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VydmUgPSBGbG9hdDMyQXJyYXkuZnJvbShvcHRpb25zLm1hcHBpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ob3B0aW9ucy5tYXBwaW5nKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRNYXAob3B0aW9ucy5tYXBwaW5nLCBvcHRpb25zLmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbGVuZ3RoOiAxMDI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXNlcyBhIG1hcHBpbmcgZnVuY3Rpb24gdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgY3VydmUuXG4gICAgICogQHBhcmFtIG1hcHBpbmcgVGhlIGZ1bmN0aW9uIHVzZWQgdG8gZGVmaW5lIHRoZSB2YWx1ZXMuXG4gICAgICogICAgICAgICAgICAgICAgVGhlIG1hcHBpbmcgZnVuY3Rpb24gdGFrZSB0d28gYXJndW1lbnRzOlxuICAgICAqICAgICAgICAgICAgICAgIHRoZSBmaXJzdCBpcyB0aGUgdmFsdWUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgKiAgICAgICAgICAgICAgICB3aGljaCBnb2VzIGZyb20gLTEgdG8gMSBvdmVyIHRoZSBudW1iZXIgb2YgZWxlbWVudHNcbiAgICAgKiAgICAgICAgICAgICAgICBpbiB0aGUgY3VydmUgYXJyYXkuIFRoZSBzZWNvbmQgYXJndW1lbnQgaXMgdGhlIGFycmF5IHBvc2l0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc2hhcGVyID0gbmV3IFRvbmUuV2F2ZVNoYXBlcigpO1xuICAgICAqIC8vIG1hcCB0aGUgaW5wdXQgc2lnbmFsIGZyb20gWy0xLCAxXSB0byBbMCwgMTBdXG4gICAgICogc2hhcGVyLnNldE1hcCgodmFsLCBpbmRleCkgPT4gKHZhbCArIDEpICogNSk7XG4gICAgICovXG4gICAgc2V0TWFwKG1hcHBpbmcsIGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IChpIC8gKGxlbiAtIDEpKSAqIDIgLSAxO1xuICAgICAgICAgICAgYXJyYXlbaV0gPSBtYXBwaW5nKG5vcm1hbGl6ZWQsIGkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3VydmUgPSBhcnJheTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhcnJheSB0byBzZXQgYXMgdGhlIHdhdmVzaGFwZXIgY3VydmUuIEZvciBsaW5lYXIgY3VydmVzXG4gICAgICogYXJyYXkgbGVuZ3RoIGRvZXMgbm90IG1ha2UgbXVjaCBkaWZmZXJlbmNlLCBidXQgZm9yIGNvbXBsZXggY3VydmVzXG4gICAgICogbG9uZ2VyIGFycmF5cyB3aWxsIHByb3ZpZGUgc21vb3RoZXIgaW50ZXJwb2xhdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIuY3VydmU7XG4gICAgfVxuICAgIHNldCBjdXJ2ZShtYXBwaW5nKSB7XG4gICAgICAgIHRoaXMuX3NoYXBlci5jdXJ2ZSA9IG1hcHBpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB3aGF0IHR5cGUgb2Ygb3ZlcnNhbXBsaW5nIChpZiBhbnkpIHNob3VsZCBiZSB1c2VkIHdoZW5cbiAgICAgKiBhcHBseWluZyB0aGUgc2hhcGluZyBjdXJ2ZS4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgY29uc3QgaXNPdmVyU2FtcGxlVHlwZSA9IFtcIm5vbmVcIiwgXCIyeFwiLCBcIjR4XCJdLnNvbWUoc3RyID0+IHN0ci5pbmNsdWRlcyhvdmVyc2FtcGxpbmcpKTtcbiAgICAgICAgYXNzZXJ0KGlzT3ZlclNhbXBsZVR5cGUsIFwib3ZlcnNhbXBsaW5nIG11c3QgYmUgZWl0aGVyICdub25lJywgJzJ4Jywgb3IgJzR4J1wiKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V2F2ZVNoYXBlci5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBBdWRpb1RvR2FpbiBjb252ZXJ0cyBhbiBpbnB1dCBpbiBBdWRpb1JhbmdlIFstMSwxXSB0byBOb3JtYWxSYW5nZSBbMCwxXS5cbiAqIFNlZSBbW0dhaW5Ub0F1ZGlvXV0uXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBBdWRpb1RvR2FpbiBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdWRpb1RvR2FpblwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbm9ybSA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHggPT4gKHggKyAxKSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2UgaW5wdXQgWy0xLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX25vcm07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgR2FpblJhbmdlIG91dHB1dCBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbm9ybTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vcm0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdWRpb1RvR2Fpbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBNdWx0aXBseSB0d28gaW5jb21pbmcgc2lnbmFscy4gT3IsIGlmIGEgbnVtYmVyIGlzIGdpdmVuIGluIHRoZSBjb25zdHJ1Y3RvcixcbiAqIG11bHRpcGxpZXMgdGhlIGluY29taW5nIHNpZ25hbCBieSB0aGF0IHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtdWx0aXBseSB0d28gc2lnbmFsc1xuICogY29uc3QgbXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KCk7XG4gKiBjb25zdCBzaWdBID0gbmV3IFRvbmUuU2lnbmFsKDMpO1xuICogY29uc3Qgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCg0KTtcbiAqIHNpZ0EuY29ubmVjdChtdWx0KTtcbiAqIHNpZ0IuY29ubmVjdChtdWx0LmZhY3Rvcik7XG4gKiAvLyBvdXRwdXQgb2YgbXVsdCBpcyAxMi5cbiAqIEBleGFtcGxlXG4gKiAvLyBtdWx0aXBseSBhIHNpZ25hbCBhbmQgYSBudW1iZXJcbiAqIGNvbnN0IG11bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgxMCk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMikuY29ubmVjdChtdWx0KTtcbiAqIC8vIHRoZSBvdXRwdXQgb2YgbXVsdCBpcyAyMC5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpcGx5IGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aXBseS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk11bHRpcGx5XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBvdmVycmlkZGVuIG9uIGNvbm5lY3Rpb25cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpcGx5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0ID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZmFjdG9yID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9tdWx0LmdhaW47XG4gICAgICAgIHRoaXMuZmFjdG9yLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU11bHRpcGx5LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIEFuIGFtcGxpdHVkZSBtb2R1bGF0ZWQgb3NjaWxsYXRvciBub2RlLiBJdCBpcyBpbXBsZW1lbnRlZCB3aXRoXG4gKiB0d28gb3NjaWxsYXRvcnMsIG9uZSB3aGljaCBtb2R1bGF0b3JzIHRoZSBvdGhlcidzIGFtcGxpdHVkZVxuICogdGhyb3VnaCBhIGdhaW4gbm9kZS5cbiAqIGBgYFxuICogICAgKy0tLS0tLS0tLS0tLS0rICAgICAgICstLS0tLS0tLS0tK1xuICogICAgfCBDYXJyaWVyIE9zYyArPi0tLS0tLT4gR2Fpbk5vZGUgfFxuICogICAgKy0tLS0tLS0tLS0tLS0rICAgICAgIHwgICAgICAgICAgKy0tLT5PdXRwdXRcbiAqICAgICAgICAgICAgICAgICAgICAgICstLS0+IGdhaW4gICAgIHxcbiAqICstLS0tLS0tLS0tLS0tLS0rICAgIHwgICArLS0tLS0tLS0tLStcbiAqIHwgTW9kdWxhdG9yIE9zYyArPi0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYW1Pc2MgPSBuZXcgVG9uZS5BTU9zY2lsbGF0b3IoMzAsIFwic2luZVwiLCBcInNxdWFyZVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMiwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBBTU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBTU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbnZlcnQgdGhlIC0xLDEgb3V0cHV0IHRvIDAsMVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbmV3IEF1ZGlvVG9HYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG5vZGUgd2hlcmUgdGhlIG1vZHVsYXRpb24gaGFwcGVuc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fY2Fycmllci5kZXR1bmU7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy5tb2R1bGF0aW9uVHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uU2NhbGUsIHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNoYWluKHRoaXMuX21vZHVsYXRpb25Ob2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImhhcm1vbmljaXR5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLFxuICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5yZXN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgY2FycmllciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGUgPSBiYXNlVHlwZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBGTU9zY2lsbGF0b3IgaW1wbGVtZW50cyBhIGZyZXF1ZW5jeSBtb2R1bGF0aW9uIHN5bnRoZXNpc1xuICogYGBgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tLS0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0tLSsgICAgIHwgQ2FycmllciBPc2MgfFxuICogfCBNb2R1bGF0b3IgT3NjICs+LS0tLS0tLT4gR2Fpbk5vZGUgICAgfCAgICAgfCAgICAgICAgICAgICArLS0tPk91dHB1dFxuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgICAgIHwgICAgICAgICAgICAgKz4tLS0tPiBmcmVxdWVuY3kgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgKy0tPiBnYWluICAgICAgICB8ICAgICArLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICAgICB8ICArLS0tLS0tLS0tLS0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0tLSsgICB8XG4gKiB8IG1vZHVsYXRpb25JbmRleCArPi0tK1xuICogKy0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBmbU9zYyA9IG5ldyBUb25lLkZNT3NjaWxsYXRvcih7XG4gKiBcdFx0ZnJlcXVlbmN5OiAyMDAsXG4gKiBcdFx0dHlwZTogXCJzcXVhcmVcIixcbiAqIFx0XHRtb2R1bGF0aW9uVHlwZTogXCJ0cmlhbmdsZVwiLFxuICogXHRcdGhhcm1vbmljaXR5OiAwLjIsXG4gKiBcdFx0bW9kdWxhdGlvbkluZGV4OiAzXG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEZNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZNT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG5vZGUgd2hlcmUgdGhlIG1vZHVsYXRpb24gaGFwcGVuc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLm1vZHVsYXRpb25UeXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubW9kdWxhdGlvbkluZGV4LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLm1vZHVsYXRpb25JbmRleCwgdGhpcy5fbW9kdWxhdGlvbk5vZGUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY29ubmVjdCh0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm1vZHVsYXRpb25JbmRleFwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImhhcm1vbmljaXR5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAyLFxuICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGUgPSBiYXNlVHlwZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogUHVsc2VPc2NpbGxhdG9yIGlzIGFuIG9zY2lsbGF0b3Igd2l0aCBjb250cm9sIG92ZXIgcHVsc2Ugd2lkdGgsXG4gKiBhbHNvIGtub3duIGFzIHRoZSBkdXR5IGN5Y2xlLiBBdCA1MCUgZHV0eSBjeWNsZSAod2lkdGggPSAwKSB0aGUgd2F2ZSBpc1xuICogYSBzcXVhcmUgd2F2ZS5cbiAqIFtSZWFkIG1vcmVdKGh0dHBzOi8vd2lnZ2xld2F2ZS53b3JkcHJlc3MuY29tLzIwMTQvMDgvMTYvcHVsc2Utd2F2ZWZvcm1zLWFuZC1oYXJtb25pY3MvKS5cbiAqIGBgYFxuICogICAgd2lkdGggPSAtMC4yNSAgICAgICAgd2lkdGggPSAwLjAgICAgICAgICAgd2lkdGggPSAwLjI1XG4gKlxuICogICArLS0tLS0rICAgICAgICAgICAgKy0tLS0tLS0rICAgICAgICsgICAgKy0tLS0tLS0rICAgICArLStcbiAqICAgfCAgICAgfCAgICAgICAgICAgIHwgICAgICAgfCAgICAgICB8ICAgICAgICAgICAgfCAgICAgfFxuICogICB8ICAgICB8ICAgICAgICAgICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgICAgICB8ICAgICB8XG4gKiArLSsgICAgICstLS0tLS0tKyAgICArICAgICAgICstLS0tLS0tKyAgICAgICAgICAgICstLS0tLStcbiAqXG4gKlxuICogICAgd2lkdGggPSAtMC41ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwLjVcbiAqXG4gKiAgICAgKy0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLSsgICArLS0tK1xuICogICAgIHwgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfFxuICogICAgIHwgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfFxuICogKy0tLSsgICArLS0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tK1xuICpcbiAqXG4gKiAgICB3aWR0aCA9IC0wLjc1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNzVcbiAqXG4gKiAgICAgICArLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLSsgKy0tLS0tK1xuICogICAgICAgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHxcbiAqICAgICAgIHwgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB8XG4gKiArLS0tLS0rICstLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKDUwLCAwLjQpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFB1bHNlT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFB1bHNlT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIndpZHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUHVsc2VPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBnYXRlIHRoZSB3aWR0aCBhbW91bnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhyZXNob2xkIHRoZSBzaWduYWwgdG8gdHVybiBpdCBpbnRvIGEgc3F1YXJlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aHJlc2ggPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB2YWwgPT4gdmFsIDw9IDAgPyAtMSA6IDEsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwid2lkdGhcIl0pO1xuICAgICAgICB0aGlzLndpZHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJhdWRpb1JhbmdlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy53aWR0aCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBcInRyaWFuZ2xlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX3RyaWFuZ2xlLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl90cmlhbmdsZS5kZXR1bmU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLmNoYWluKHRoaXMuX3RocmVzaCwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLndpZHRoLmNoYWluKHRoaXMuX3dpZHRoR2F0ZSwgdGhpcy5fdGhyZXNoKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wid2lkdGhcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJwdWxzZVwiLFxuICAgICAgICAgICAgd2lkdGg6IDAuMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuc3RvcCh0aW1lKTtcbiAgICAgICAgLy8gdGhlIHdpZHRoIGlzIHN0aWxsIGNvbm5lY3RlZCB0byB0aGUgb3V0cHV0LlxuICAgICAgICAvLyB0aGF0IG5lZWRzIHRvIGJlIHN0b3BwZWQgYWxzb1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwaGFzZSBvZiB0aGUgb3NjaWxsYXRvciBpbiBkZWdyZWVzLlxuICAgICAqL1xuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RyaWFuZ2xlLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHVsc2VcIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHVsc2VcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2VUeXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBBbHdheXMgcmV0dXJucyBcInB1bHNlXCIuXG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwdWxzZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBDYW5ub3Qgc2V0IHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGVcbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTm8gcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKkludGVybmFsIHVzZSogVGhlIGNhcnJpZXIgb3NjaWxsYXRvciB0eXBlIGlzIGZlZCB0aHJvdWdoIHRoZVxuICAgICAqIHdhdmVzaGFwZXIgbm9kZSB0byBjcmVhdGUgdGhlIHB1bHNlLiBVc2luZyBkaWZmZXJlbnQgY2FycmllciBvc2NpbGxhdG9yc1xuICAgICAqIGNoYW5nZXMgb3NjaWxsYXRvcidzIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIHNldCBjYXJyaWVyVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCBtZXRob2QuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2lkdGguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QdWxzZU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBGYXRPc2NpbGxhdG9yIGlzIGFuIGFycmF5IG9mIG9zY2lsbGF0b3JzIHdpdGggZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9yc1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZhdE9zYyA9IG5ldyBUb25lLkZhdE9zY2lsbGF0b3IoXCJBYjNcIiwgXCJzYXd0b290aFwiLCA0MCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBGYXRPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmF0T3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJzcHJlYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGYXRPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2Ygb3NjaWxsYXRvcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInNwcmVhZFwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuX3BoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBvcHRpb25zLnBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvcHRpb25zLnBhcnRpYWxDb3VudDtcbiAgICAgICAgLy8gc2V0IHRoZSBjb3VudCBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5jb3VudCA9IG9wdGlvbnMuY291bnQ7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb3VudDogMyxcbiAgICAgICAgICAgIHNwcmVhZDogMjAsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RvcCh0aW1lKSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnJlc3RhcnQodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgYWxsIG9mIHRoZSBvc2NpbGxhdG9yc1xuICAgICAqL1xuICAgIF9mb3JFYWNoKGl0ZXJhdG9yKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKHRoaXMuX29zY2lsbGF0b3JzW2ldLCBpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnR5cGUgPSB0eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRldHVuZSBzcHJlYWQgYmV0d2VlbiB0aGUgb3NjaWxsYXRvcnMuIElmIFwiY291bnRcIiBpc1xuICAgICAqIHNldCB0byAzIG9zY2lsbGF0b3JzIGFuZCB0aGUgXCJzcHJlYWRcIiBpcyBzZXQgdG8gNDAsXG4gICAgICogdGhlIHRocmVlIG9zY2lsbGF0b3JzIHdvdWxkIGJlIGRldHVuZWQgbGlrZSB0aGlzOiBbLTIwLCAwLCAyMF1cbiAgICAgKiBmb3IgYSB0b3RhbCBkZXR1bmUgc3ByZWFkIG9mIDQwIGNlbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIGZhdE9zYy5zcHJlYWQgPSA3MDtcbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3ByZWFkO1xuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICB0aGlzLl9zcHJlYWQgPSBzcHJlYWQ7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IC1zcHJlYWQgLyAyO1xuICAgICAgICAgICAgY29uc3Qgc3RlcCA9IHNwcmVhZCAvICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goKG9zYywgaSkgPT4gb3NjLmRldHVuZS52YWx1ZSA9IHN0YXJ0ICsgc3RlcCAqIGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9ycy4gTXVzdCBiZSBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiAxLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkMjM1wiLCBcInNhd3Rvb3RoXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIHVzZSA0IHNhd3Rvb3RoIG9zY2lsbGF0b3JzXG4gICAgICogZmF0T3NjLmNvdW50ID0gNDtcbiAgICAgKi9cbiAgICBnZXQgY291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7XG4gICAgfVxuICAgIHNldCBjb3VudChjb3VudCkge1xuICAgICAgICBhc3NlcnRSYW5nZShjb3VudCwgMSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggIT09IGNvdW50KSB7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIHRoZSBwcmV2aW91cyBvc2NpbGxhdG9yc1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3NjID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIHZvbHVtZTogLTYgLSBjb3VudCAqIDEuMSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgcGhhc2U6IHRoaXMuX3BoYXNlICsgKGkgLyBjb3VudCkgKiAzNjAsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudDogdGhpcy5fcGFydGlhbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBvbnN0b3A6IGkgPT09IDAgPyAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSA6IG5vT3AsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgICAgICAgICBvc2MucGFydGlhbHMgPSB0aGlzLl9wYXJ0aWFscztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KG9zYy5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIG9zYy5kZXR1bmUub3ZlcnJpZGRlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIG9zYy5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yc1tpXSA9IG9zYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHNldCB0aGUgc3ByZWFkXG4gICAgICAgICAgICB0aGlzLnNwcmVhZCA9IHRoaXMuX3NwcmVhZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdGFydCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX3BoYXNlID0gcGhhc2U7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goKG9zYywgaSkgPT4gb3NjLnBoYXNlID0gdGhpcy5fcGhhc2UgKyAoaSAvIHRoaXMuY291bnQpICogMzYwKTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0uYmFzZVR5cGU7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuYmFzZVR5cGUgPSBiYXNlVHlwZSk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0aGlzLl9vc2NpbGxhdG9yc1swXS50eXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aDtcbiAgICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IFwiY3VzdG9tXCI7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucGFydGlhbHMgPSBwYXJ0aWFscyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50KTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuX29zY2lsbGF0b3JzWzBdLnR5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5kaXNwb3NlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GYXRPc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgUHVsc2VPc2NpbGxhdG9yIH0gZnJvbSBcIi4vUHVsc2VPc2NpbGxhdG9yXCI7XG4vKipcbiAqIFBXTU9zY2lsbGF0b3IgbW9kdWxhdGVzIHRoZSB3aWR0aCBvZiBhIFRvbmUuUHVsc2VPc2NpbGxhdG9yXG4gKiBhdCB0aGUgbW9kdWxhdGlvbkZyZXF1ZW5jeS4gVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjb250aW51b3VzbHlcbiAqIGNoYW5naW5nIHRoZSB0aW1icmUgb2YgdGhlIG9zY2lsbGF0b3IgYnkgYWx0ZXJpbmcgdGhlIGhhcm1vbmljc1xuICogZ2VuZXJhdGVkLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBwd20gPSBuZXcgVG9uZS5QV01Pc2NpbGxhdG9yKDYwLCAwLjMpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBXTU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQV01Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibW9kdWxhdGlvbkZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBXTU9zY2lsbGF0b3JcIjtcbiAgICAgICAgdGhpcy5zb3VyY2VUeXBlID0gXCJwd21cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNjYWxlIHRoZSBvc2NpbGxhdG9yIHNvIGl0IGRvZXNuJ3QgZ28gc2lsZW50XG4gICAgICAgICAqIGF0IHRoZSBleHRyZW1lIHZhbHVlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjYWxlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fcHVsc2UgPSBuZXcgUHVsc2VPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5tb2R1bGF0aW9uRnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY2hhbmdlIHRoZSBwdWxzZSBvc2NpbGxhdG9yIHR5cGVcbiAgICAgICAgdGhpcy5fcHVsc2UuY2FycmllclR5cGUgPSBcInNpbmVcIjtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uRnJlcXVlbmN5ID0gdGhpcy5fcHVsc2UuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fc2NhbGUsIHRoaXMuX3B1bHNlLndpZHRoKTtcbiAgICAgICAgdGhpcy5fcHVsc2UuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm1vZHVsYXRpb25GcmVxdWVuY3lcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIG1vZHVsYXRpb25GcmVxdWVuY3k6IDAuNCxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJwd21cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiByZXN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2UucmVzdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHdtXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB3bVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZVR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHdtXCIuXG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwd21cIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhcnRpYWxzIG9mIHRoZSB3YXZlZm9ybS4gQ2Fubm90IHNldCBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5vIHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwaGFzZSBvZiB0aGUgb3NjaWxsYXRvciBpbiBkZWdyZWVzLlxuICAgICAqL1xuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3B1bHNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QV01Pc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc051bWJlciwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IEFNT3NjaWxsYXRvciB9IGZyb20gXCIuL0FNT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgRmF0T3NjaWxsYXRvciB9IGZyb20gXCIuL0ZhdE9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IEZNT3NjaWxsYXRvciB9IGZyb20gXCIuL0ZNT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQdWxzZU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QdWxzZU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFBXTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QV01Pc2NpbGxhdG9yXCI7XG5jb25zdCBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcCA9IHtcbiAgICBhbTogQU1Pc2NpbGxhdG9yLFxuICAgIGZhdDogRmF0T3NjaWxsYXRvcixcbiAgICBmbTogRk1Pc2NpbGxhdG9yLFxuICAgIG9zY2lsbGF0b3I6IE9zY2lsbGF0b3IsXG4gICAgcHVsc2U6IFB1bHNlT3NjaWxsYXRvcixcbiAgICBwd206IFBXTU9zY2lsbGF0b3IsXG59O1xuLyoqXG4gKiBPbW5pT3NjaWxsYXRvciBhZ2dyZWdhdGVzIGFsbCBvZiB0aGUgb3NjaWxsYXRvciB0eXBlcyBpbnRvIG9uZS5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKFwiQyM0XCIsIFwicHdtXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE9tbmlPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT21uaU9zY2lsbGF0b3JcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICAgICAgLy8gc2V0IHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMuc2V0KG9wdGlvbnMpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFB1bHNlT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBQV01Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIENhbiBiZSBhbnkgb2YgdGhlIGJhc2ljIHR5cGVzOiBzaW5lLCBzcXVhcmUsIHRyaWFuZ2xlLCBzYXd0b290aC4gT3JcbiAgICAgKiBwcmVmaXggdGhlIGJhc2ljIHR5cGVzIHdpdGggXCJmbVwiLCBcImFtXCIsIG9yIFwiZmF0XCIgdG8gdXNlIHRoZSBGTU9zY2lsbGF0b3IsIEFNT3NjaWxsYXRvciBvciBGYXRPc2NpbGxhdG9yXG4gICAgICogdHlwZXMuIFRoZSBvc2NpbGxhdG9yIGNvdWxkIGFsc28gYmUgc2V0IHRvIFwicHdtXCIgb3IgXCJwdWxzZVwiLiBBbGwgb2YgdGhlIHBhcmFtZXRlcnMgb2YgdGhlXG4gICAgICogb3NjaWxsYXRvcidzIGNsYXNzIGFyZSBhY2Nlc3NpYmxlIHdoZW4gdGhlIG9zY2lsbGF0b3IgaXMgc2V0IHRvIHRoYXQgdHlwZSwgYnV0IHRocm93cyBhbiBlcnJvclxuICAgICAqIHdoZW4gaXQncyBub3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBvbW5pT3NjLnR5cGUgPSBcInB3bVwiO1xuICAgICAqIC8vIG1vZHVsYXRpb25GcmVxdWVuY3kgaXMgcGFyYW1ldGVyIHdoaWNoIGlzIGF2YWlsYWJsZVxuICAgICAqIC8vIG9ubHkgd2hlbiB0aGUgdHlwZSBpcyBcInB3bVwiLlxuICAgICAqIG9tbmlPc2MubW9kdWxhdGlvbkZyZXF1ZW5jeS52YWx1ZSA9IDAuNTtcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgbGV0IHByZWZpeCA9IFwiXCI7XG4gICAgICAgIGlmIChbXCJhbVwiLCBcImZtXCIsIFwiZmF0XCJdLnNvbWUocCA9PiB0aGlzLl9zb3VyY2VUeXBlID09PSBwKSkge1xuICAgICAgICAgICAgcHJlZml4ID0gdGhpcy5fc291cmNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJlZml4ICsgdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGlmICh0eXBlLnN1YnN0cigwLCAyKSA9PT0gXCJmbVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwiZm1cIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUuc3Vic3RyKDAsIDIpID09PSBcImFtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJhbVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZS5zdWJzdHIoMCwgMykgPT09IFwiZmF0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJmYXRcIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJwd21cIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSBcInB1bHNlXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJwdWxzZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJvc2NpbGxhdG9yXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSBpcyBhbiBlbXB0eSBhcnJheSB3aGVuIHRoZSB0eXBlIGlzIG5vdCBcImN1c3RvbVwiLlxuICAgICAqIFRoaXMgaXMgbm90IGF2YWlsYWJsZSBvbiBcInB3bVwiIGFuZCBcInB1bHNlXCIgb3NjaWxsYXRvciB0eXBlcy5cbiAgICAgKiBTZWUgW1tPc2NpbGxhdG9yLnBhcnRpYWxzXV1cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiYgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpICYmICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQocHJvcHMpIHtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSB0eXBlIGlzIHNldCBmaXJzdFxuICAgICAgICBpZiAoUmVmbGVjdC5oYXMocHJvcHMsIFwidHlwZVwiKSAmJiBwcm9wcy50eXBlKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBwcm9wcy50eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZW4gc2V0IHRoZSByZXN0XG4gICAgICAgIHN1cGVyLnNldChwcm9wcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjb25uZWN0IHRoZSBvc2NpbGxhdG9yIHRvIHRoZSBmcmVxdWVuY3kgYW5kIGRldHVuZSBzaWduYWxzXG4gICAgICovXG4gICAgX2NyZWF0ZU5ld09zY2lsbGF0b3Iob3NjVHlwZSkge1xuICAgICAgICBpZiAob3NjVHlwZSAhPT0gdGhpcy5fc291cmNlVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlVHlwZSA9IG9zY1R5cGU7XG4gICAgICAgICAgICBjb25zdCBPc2NDb25zdHJ1Y3RvciA9IE9tbmlPc2NpbGxhdG9yU291cmNlTWFwW29zY1R5cGVdO1xuICAgICAgICAgICAgLy8gc2hvcnQgZGVsYXkgdG8gYXZvaWQgY2xpY2tzIG9uIHRoZSBjaGFuZ2VcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZE9zYyA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICAgICAgb2xkT3NjLnN0b3Aobm93KTtcbiAgICAgICAgICAgICAgICAvLyBkaXNwb3NlIHRoZSBvbGQgb25lXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoKCkgPT4gb2xkT3NjLmRpc3Bvc2UoKSwgdGhpcy5ibG9ja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG5ldyBPc2NDb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5kZXR1bmUpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iub25zdG9wID0gKCkgPT4gdGhpcy5vbnN0b3AodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KG5vdyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNvdXJjZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKDQ0MCwgXCJmbXNxdWFyZVwiKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvbW5pT3NjLnNvdXJjZVR5cGUpOyAvLyAnZm0nXG4gICAgICovXG4gICAgZ2V0IHNvdXJjZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2VUeXBlO1xuICAgIH1cbiAgICBzZXQgc291cmNlVHlwZShzVHlwZSkge1xuICAgICAgICAvLyB0aGUgYmFzZXR5cGUgZGVmYXVsdHMgdG8gc2luZVxuICAgICAgICBsZXQgYmFzZVR5cGUgPSBcInNpbmVcIjtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IudHlwZSAhPT0gXCJwd21cIiAmJiB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgIT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgYmFzZVR5cGUgPSB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB0eXBlXG4gICAgICAgIGlmIChzVHlwZSA9PT0gXCJmbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImZtXCIgKyBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJhbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImFtXCIgKyBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJmYXRcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJmYXRcIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcIm9zY2lsbGF0b3JcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJwdWxzZVwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcInB3bVwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIF9nZXRPc2NUeXBlKG9zYywgc291cmNlVHlwZSkge1xuICAgICAgICByZXR1cm4gb3NjIGluc3RhbmNlb2YgT21uaU9zY2lsbGF0b3JTb3VyY2VNYXBbc291cmNlVHlwZV07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIFNlZSBbW09zY2lsbGF0b3IuYmFzZVR5cGVdXVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKDQ0MCwgXCJmbXNxdWFyZTRcIik7XG4gICAgICogY29uc29sZS5sb2cob21uaU9zYy5zb3VyY2VUeXBlLCBvbW5pT3NjLmJhc2VUeXBlLCBvbW5pT3NjLnBhcnRpYWxDb3VudCk7XG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIGlmICghdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpICYmXG4gICAgICAgICAgICAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSAmJlxuICAgICAgICAgICAgYmFzZVR5cGUgIT09IFwicHVsc2VcIiAmJiBiYXNlVHlwZSAhPT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHNvdXJjZVR5cGUgPT09IFwicHVsc2VcIi5cbiAgICAgKiBTZWUgW1tQV01Pc2NpbGxhdG9yLndpZHRoXV1cbiAgICAgKi9cbiAgICBnZXQgd2lkdGgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLndpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRldHVuZWQgb3NjaWxsYXRvcnMgd2hlbiBzb3VyY2VUeXBlID09PSBcImZhdFwiLlxuICAgICAqIFNlZSBbW0ZhdE9zY2lsbGF0b3IuY291bnRdXVxuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmNvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgY291bnQoY291bnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikgJiYgaXNOdW1iZXIoY291bnQpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvdW50ID0gY291bnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRldHVuZSBzcHJlYWQgYmV0d2VlbiB0aGUgb3NjaWxsYXRvcnMgd2hlbiBzb3VyY2VUeXBlID09PSBcImZhdFwiLlxuICAgICAqIFNlZSBbW0ZhdE9zY2lsbGF0b3IuY291bnRdXVxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpICYmIGlzTnVtYmVyKHNwcmVhZCkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3ByZWFkID0gc3ByZWFkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvci4gT25seSBpZiB0aGUgb3NjaWxsYXRvciBpcyBzZXQgdG8gXCJhbVwiIG9yIFwiZm1cIiB0eXBlcy5cbiAgICAgKiBTZWUgW1tBTU9zY2lsbGF0b3JdXSBvciBbW0ZNT3NjaWxsYXRvcl1dXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvblR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZShtVHlwZSkge1xuICAgICAgICBpZiAoKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpICYmIGlzU3RyaW5nKG1UeXBlKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZSA9IG1UeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtb2R1bGF0aW9uIGluZGV4IHdoZW4gdGhlIHNvdXJjZVR5cGUgPT09IFwiZm1cIlxuICAgICAqIFNlZSBbW0ZNT3NjaWxsYXRvcl1dLlxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uSW5kZXgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25JbmRleDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFybW9uaWNpdHkgaXMgdGhlIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSBjYXJyaWVyIGFuZCB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JzLlxuICAgICAqIFNlZSBbW0FNT3NjaWxsYXRvcl1dIG9yIFtbRk1Pc2NpbGxhdG9yXV1cbiAgICAgKi9cbiAgICBnZXQgaGFybW9uaWNpdHkoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5oYXJtb25pY2l0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb25GcmVxdWVuY3kgU2lnbmFsIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc291cmNlVHlwZSA9PT0gXCJwd21cIlxuICAgICAqIHNlZSBbW1BXTU9zY2lsbGF0b3JdXVxuICAgICAqIEBtaW4gMC4xXG4gICAgICogQG1heCA1XG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25GcmVxdWVuY3koKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uRnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T21uaU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogQWRkIGEgc2lnbmFsIGFuZCBhIG51bWJlciBvciB0d28gc2lnbmFscy4gV2hlbiBubyB2YWx1ZSBpc1xuICogcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLCBUb25lLkFkZCB3aWxsIHN1bSBpbnB1dCBhbmQgYGFkZGVuZGBcbiAqIElmIGEgdmFsdWUgaXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLCB0aGUgaXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgaW5wdXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhZGQgPSBuZXcgVG9uZS5BZGQoMikudG9EZXN0aW5hdGlvbigpO1xuICogXHRhZGQuYWRkZW5kLnNldFZhbHVlQXRUaW1lKDEsIDAuMik7XG4gKiBcdGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgyKTtcbiAqIFx0Ly8gYWRkIGEgc2lnbmFsIGFuZCBhIHNjYWxhclxuICogXHRzaWduYWwuY29ubmVjdChhZGQpO1xuICogXHRzaWduYWwuc2V0VmFsdWVBdFRpbWUoMSwgMC4xKTtcbiAqIH0sIDAuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBBZGQgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFkZC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQWRkXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc3VtbWluZyBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdW0gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgd2hpY2ggaXMgYWRkZWQgdG8gdGhlIGlucHV0IHNpZ25hbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRlbmQgPSB0aGlzLl9wYXJhbTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLl9jb25zdGFudFNvdXJjZSwgdGhpcy5fc3VtKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1bS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFkZC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cbiAqIFNjYWxlcyBhIE5vcm1hbFJhbmdlIGlucHV0IHRvIGJldHdlZW5cbiAqIG91dHB1dE1pbiBhbmQgb3V0cHV0TWF4LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzY2FsZSA9IG5ldyBUb25lLlNjYWxlKDUwLCAxMDApO1xuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChzY2FsZSk7XG4gKiAvLyB0aGUgb3V0cHV0IG9mIHNjYWxlIGVxdWFscyA3NVxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgU2NhbGUgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2NhbGVcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCJdKTtcbiAgICAgICAgdGhpcy5fbXVsdCA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubWF4IC0gb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hZGQgPSB0aGlzLm91dHB1dCA9IG5ldyBBZGQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWluID0gb3B0aW9ucy5taW47XG4gICAgICAgIHRoaXMuX21heCA9IG9wdGlvbnMubWF4O1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBudW1iZXIgaXMgb3V0cHV0IHdoZW4gdGhlIHZhbHVlIGlucHV0IHZhbHVlIGlzIDAuXG4gICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbjtcbiAgICB9XG4gICAgc2V0IG1pbihtaW4pIHtcbiAgICAgICAgdGhpcy5fbWluID0gbWluO1xuICAgICAgICB0aGlzLl9zZXRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgbnVtYmVyIGlzIG91dHB1dCB3aGVuIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAxLlxuICAgICAqL1xuICAgIGdldCBtYXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXg7XG4gICAgfVxuICAgIHNldCBtYXgobWF4KSB7XG4gICAgICAgIHRoaXMuX21heCA9IG1heDtcbiAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc2V0IHRoZSB2YWx1ZXNcbiAgICAgKi9cbiAgICBfc2V0UmFuZ2UoKSB7XG4gICAgICAgIHRoaXMuX2FkZC52YWx1ZSA9IHRoaXMuX21pbjtcbiAgICAgICAgdGhpcy5fbXVsdC52YWx1ZSA9IHRoaXMuX21heCAtIHRoaXMuX21pbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hZGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2NhbGUuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdCwgZGlzY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFRvbmUuWmVybyBvdXRwdXRzIDAncyBhdCBhdWRpby1yYXRlLiBUaGUgcmVhc29uIHRoaXMgaGFzIHRvIGJlXG4gKiBpdCdzIG93biBjbGFzcyBpcyB0aGF0IG1hbnkgYnJvd3NlcnMgb3B0aW1pemUgb3V0IFRvbmUuU2lnbmFsXG4gKiB3aXRoIGEgdmFsdWUgb2YgMCBhbmQgd2lsbCBub3QgcHJvY2VzcyBub2RlcyBmdXJ0aGVyIGRvd24gdGhlIGdyYXBoLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgWmVybyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhaZXJvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJaZXJvXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZ2FpbiBub2RlIHdoaWNoIGNvbm5lY3RzIHRoZSBjb25zdGFudCBzb3VyY2UgdG8gdGhlIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2FpbiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogT25seSBvdXRwdXRzIDBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2FpbjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5vIGlucHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGNvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDApLCB0aGlzLl9nYWluKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGRpc2Nvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDApLCB0aGlzLl9nYWluKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9WmVyby5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgQXVkaW9Ub0dhaW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0F1ZGlvVG9HYWluXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwsIFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBaZXJvIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9aZXJvXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuLyoqXG4gKiBMRk8gc3RhbmRzIGZvciBsb3cgZnJlcXVlbmN5IG9zY2lsbGF0b3IuIExGTyBwcm9kdWNlcyBhbiBvdXRwdXQgc2lnbmFsXG4gKiB3aGljaCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gQXVkaW9QYXJhbSBvciBUb25lLlNpZ25hbFxuICogaW4gb3JkZXIgdG8gbW9kdWxhdGUgdGhhdCBwYXJhbWV0ZXIgd2l0aCBhbiBvc2NpbGxhdG9yLiBUaGUgTEZPIGNhblxuICogYWxzbyBiZSBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydCB0byBzdGFydC9zdG9wIGFuZCBjaGFuZ2Ugd2hlbiB0aGUgdGVtcG8gY2hhbmdlcy5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgbGZvID0gbmV3IFRvbmUuTEZPKFwiNG5cIiwgNDAwLCA0MDAwKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIH0sIDAuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBMRk8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTEZPLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibWluXCIsIFwibWF4XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTEZPXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgdGhhdCB0aGUgTEZPIG91dHB1dHMgd2hlbiBpdCdzIHN0b3BwZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIHByaXZhdGUgcGxhY2Vob2xkZXIgZm9yIHRoZSB1bml0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdW5pdHMgPSBcIm51bWJlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIGlucHV0IHZhbHVlIGlzIGNvbnZlcnRlZCB1c2luZyB0aGUgW1t1bml0c11dXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbnZlcnQgPSB0cnVlO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSBtZXRob2RzIGJvcnJvd2VkIGZyb20gUGFyYW1cbiAgICAgICAgICovXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fZnJvbVR5cGUgPSBQYXJhbS5wcm90b3R5cGUuX2Zyb21UeXBlO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX3RvVHlwZSA9IFBhcmFtLnByb3RvdHlwZS5fdG9UeXBlO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2lzID0gUGFyYW0ucHJvdG90eXBlLl9pcztcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jbGFtcFZhbHVlID0gUGFyYW0ucHJvdG90eXBlLl9jbGFtcFZhbHVlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTEZPLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibWluXCIsIFwibWF4XCJdKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG5ldyBPc2NpbGxhdG9yKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5hbXBsaXR1ZGUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hbXBsaXR1ZGUgPSB0aGlzLl9hbXBsaXR1ZGVHYWluLmdhaW47XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImF1ZGlvUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5femVyb3MgPSBuZXcgWmVybyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYTJnID0gbmV3IEF1ZGlvVG9HYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9zY2FsZXIgPSB0aGlzLm91dHB1dCA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXg6IG9wdGlvbnMubWF4LFxuICAgICAgICAgICAgbWluOiBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuICAgICAgICB0aGlzLm1pbiA9IG9wdGlvbnMubWluO1xuICAgICAgICB0aGlzLm1heCA9IG9wdGlvbnMubWF4O1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY2hhaW4odGhpcy5fYW1wbGl0dWRlR2FpbiwgdGhpcy5fYTJnLCB0aGlzLl9zY2FsZXIpO1xuICAgICAgICB0aGlzLl96ZXJvcy5jb25uZWN0KHRoaXMuX2EyZyk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuY29ubmVjdCh0aGlzLl9hMmcpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJhbXBsaXR1ZGVcIiwgXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGFtcGxpdHVkZTogMSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogXCI0blwiLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBMRk8uXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdGhlIExGTyB3aWxsIHN0YXJ0XG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBMRk8uXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRoZSBMRk8gd2lsbCBzdG9wXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSh0aGlzLl9zdG9wcGVkVmFsdWUsIHRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzdGFydC9zdG9wL3BhdXNlIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBhbmQgdGhlIGZyZXF1ZW5jeSB0byB0aGUgYnBtIG9mIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxmbyA9IG5ldyBUb25lLkxGTyhcIjhuXCIpO1xuICAgICAqIGxmby5zeW5jKCkuc3RhcnQoMCk7XG4gICAgICogLy8gdGhlIHJhdGUgb2YgdGhlIExGTyB3aWxsIGFsd2F5cyBiZSBhbiBlaWdodGggbm90ZSwgZXZlbiBhcyB0aGUgdGVtcG8gY2hhbmdlc1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3luYygpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3koKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHVuc3luYyB0aGUgTEZPIGZyb20gdHJhbnNwb3J0IGNvbnRyb2xcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudW5zeW5jRnJlcXVlbmN5KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZnRlciB0aGUgb3NjaWxsYXRvciB3YXZlZm9ybSBpcyB1cGRhdGVkLCByZXNldCB0aGUgYF9zdG9wcGVkU2lnbmFsYCB2YWx1ZSB0byBtYXRjaCB0aGUgdXBkYXRlZCB3YXZlZm9ybVxuICAgICAqL1xuICAgIF9zZXRTdG9wcGVkVmFsdWUoKSB7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IHRoaXMuX29zY2lsbGF0b3IuZ2V0SW5pdGlhbFZhbHVlKCk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwudmFsdWUgPSB0aGlzLl9zdG9wcGVkVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCBtaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fc2NhbGVyLm1pbik7XG4gICAgfVxuICAgIHNldCBtaW4obWluKSB7XG4gICAgICAgIG1pbiA9IHRoaXMuX2Zyb21UeXBlKG1pbik7XG4gICAgICAgIHRoaXMuX3NjYWxlci5taW4gPSBtaW47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG91dHB1dCBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCBtYXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fc2NhbGVyLm1heCk7XG4gICAgfVxuICAgIHNldCBtYXgobWF4KSB7XG4gICAgICAgIG1heCA9IHRoaXMuX2Zyb21UeXBlKG1heCk7XG4gICAgICAgIHRoaXMuX3NjYWxlci5tYXggPSBtYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yOiBTZWUgW1tPc2NpbGxhdG9yLnR5cGVdXVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvcidzIHBhcnRpYWxzIGFycmF5OiBTZWUgW1tPc2NpbGxhdG9yLnBhcnRpYWxzXV1cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdXRwdXQgdW5pdHMgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgdW5pdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl91bml0cztcbiAgICB9XG4gICAgc2V0IHVuaXRzKHZhbCkge1xuICAgICAgICBjb25zdCBjdXJyZW50TWluID0gdGhpcy5taW47XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNYXggPSB0aGlzLm1heDtcbiAgICAgICAgLy8gY29udmVydCB0aGUgbWluIGFuZCB0aGUgbWF4XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdmFsO1xuICAgICAgICB0aGlzLm1pbiA9IGN1cnJlbnRNaW47XG4gICAgICAgIHRoaXMubWF4ID0gY3VycmVudE1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiIG9yIFwic3RvcHBlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBub2RlIHRoZSBkZXN0aW5hdGlvbiB0byBjb25uZWN0IHRvXG4gICAgICogQHBhcmFtIG91dHB1dE51bSB0aGUgb3B0aW9uYWwgb3V0cHV0IG51bWJlclxuICAgICAqIEBwYXJhbSBpbnB1dE51bSB0aGUgaW5wdXQgbnVtYmVyXG4gICAgICovXG4gICAgY29ubmVjdChub2RlLCBvdXRwdXROdW0sIGlucHV0TnVtKSB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgUGFyYW0gfHwgbm9kZSBpbnN0YW5jZW9mIFNpZ25hbCkge1xuICAgICAgICAgICAgdGhpcy5jb252ZXJ0ID0gbm9kZS5jb252ZXJ0O1xuICAgICAgICAgICAgdGhpcy51bml0cyA9IG5vZGUudW5pdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBub2RlLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl96ZXJvcy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2EyZy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmFtcGxpdHVkZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxGTy5qcy5tYXAiLCJpbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuL0RlYnVnXCI7XG4vKipcbiAqIEFzc2VydCB0aGF0IHRoZSBudW1iZXIgaXMgaW4gdGhlIGdpdmVuIHJhbmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobWluLCBtYXggPSBJbmZpbml0eSkge1xuICAgIGNvbnN0IHZhbHVlTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlTWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGFzc2VydFJhbmdlKG5ld1ZhbHVlLCBtaW4sIG1heCk7XG4gICAgICAgICAgICAgICAgdmFsdWVNYXAuc2V0KHRoaXMsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbn1cbi8qKlxuICogQ29udmVydCB0aGUgdGltZSB0byBzZWNvbmRzIGFuZCBhc3NlcnQgdGhhdCB0aGUgdGltZSBpcyBpbiBiZXR3ZWVuIHRoZSB0d29cbiAqIHZhbHVlcyB3aGVuIGJlaW5nIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVSYW5nZShtaW4sIG1heCA9IEluZmluaXR5KSB7XG4gICAgY29uc3QgdmFsdWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHMobmV3VmFsdWUpLCBtaW4sIG1heCk7XG4gICAgICAgICAgICAgICAgdmFsdWVNYXAuc2V0KHRoaXMsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlY29yYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIsIF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBQbGF5ZXIgaXMgYW4gYXVkaW8gZmlsZSBwbGF5ZXIgd2l0aCBzdGFydCwgbG9vcCwgYW5kIHN0b3AgZnVuY3Rpb25zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2dvbmdfMS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcGxheSBhcyBzb29uIGFzIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBsYXllciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsYXllclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBhY3RpdmUgYnVmZmVyIHNvdXJjZSBub2Rlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoe1xuICAgICAgICAgICAgb25sb2FkOiB0aGlzLl9vbmxvYWQuYmluZCh0aGlzLCBvcHRpb25zLm9ubG9hZCksXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgICAgICByZXZlcnNlOiBvcHRpb25zLnJldmVyc2UsXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdXRvc3RhcnQgPSBvcHRpb25zLmF1dG9zdGFydDtcbiAgICAgICAgdGhpcy5fbG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLmZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLmZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF1dG9zdGFydDogZmFsc2UsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZCB0aGUgYXVkaW8gZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogRGVjb2RlcyB0aGUgYXVkaW8gYXN5bmNocm9ub3VzbHkgYW5kIGludm9rZXNcbiAgICAgKiB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIE5vdGU6IHRoaXMgZG9lcyBub3QgbmVlZCB0byBiZSBjYWxsZWQgaWYgYSB1cmxcbiAgICAgKiB3YXMgcGFzc2VkIGluIHRvIHRoZSBjb25zdHJ1Y3Rvci4gT25seSB1c2UgdGhpc1xuICAgICAqIGlmIHlvdSB3YW50IHRvIG1hbnVhbGx5IGxvYWQgYSBuZXcgdXJsLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIEZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKi9cbiAgICBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQgdGhpcy5fYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgICAgIHRoaXMuX29ubG9hZCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBjYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIF9vbmxvYWQoY2FsbGJhY2sgPSBub09wKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGlmICh0aGlzLmF1dG9zdGFydCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGNhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBkb25lIHBsYXlpbmcuXG4gICAgICovXG4gICAgX29uU291cmNlRW5kKHNvdXJjZSkge1xuICAgICAgICAvLyBpbnZva2UgdGhlIG9uc3RvcCBmdW5jdGlvblxuICAgICAgICB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICAgICAgLy8gZGVsZXRlIHRoZSBzb3VyY2UgZnJvbSB0aGUgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5kZWxldGUoc291cmNlKTtcbiAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2l6ZSA9PT0gMCAmJiAhdGhpcy5fc3luY2VkICYmXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgJ2ltcGxpY2l0RW5kJyBldmVudCBhbmQgcmVwbGFjZSB3aXRoIGFuIGV4cGxpY2l0IGVuZFxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRoaXMubm93KCkpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBsYXkgdGhlIGJ1ZmZlciBhdCB0aGUgZ2l2ZW4gc3RhcnRUaW1lLiBPcHRpb25hbGx5IGFkZCBhbiBvZmZzZXRcbiAgICAgKiBhbmQvb3IgZHVyYXRpb24gd2hpY2ggd2lsbCBwbGF5IHRoZSBidWZmZXIgZnJvbSBhIHBvc2l0aW9uXG4gICAgICogd2l0aGluIHRoZSBidWZmZXIgZm9yIHRoZSBnaXZlbiBkdXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIuc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdGFydCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RhcnQoc3RhcnRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIC8vIGlmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcFN0YXJ0IHBvaW50XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5fbG9vcFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgMFxuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlIHZhbHVlcyBpbiBzZWNvbmRzXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgZHVyYXRpb24gd2hpY2ggaXMgZWl0aGVyIHRoZSBwYXNzZWQgaW4gZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5kdXJhdGlvbiAtIG9mZnNldFxuICAgICAgICBjb25zdCBvcmlnRHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgZHVyYXRpb24gPSBkZWZhdWx0QXJnKGR1cmF0aW9uLCBNYXRoLm1heCh0aGlzLl9idWZmZXIuZHVyYXRpb24gLSBjb21wdXRlZE9mZnNldCwgMCkpO1xuICAgICAgICBsZXQgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgLy8gc2NhbGUgaXQgYnkgdGhlIHBsYXliYWNrIHJhdGVcbiAgICAgICAgY29tcHV0ZWREdXJhdGlvbiA9IGNvbXB1dGVkRHVyYXRpb24gLyB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgICAgIC8vIGdldCB0aGUgc3RhcnQgdGltZVxuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICAvLyBtYWtlIHRoZSBzb3VyY2VcbiAgICAgICAgY29uc3Qgc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgdXJsOiB0aGlzLl9idWZmZXIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlSW46IHRoaXMuZmFkZUluLFxuICAgICAgICAgICAgZmFkZU91dDogdGhpcy5mYWRlT3V0LFxuICAgICAgICAgICAgbG9vcDogdGhpcy5fbG9vcCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IHRoaXMuX2xvb3BFbmQsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IHRoaXMuX2xvb3BTdGFydCxcbiAgICAgICAgICAgIG9uZW5kZWQ6IHRoaXMuX29uU291cmNlRW5kLmJpbmQodGhpcyksXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMuX3BsYXliYWNrUmF0ZSxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIC8vIHNldCB0aGUgbG9vcGluZyBwcm9wZXJ0aWVzXG4gICAgICAgIGlmICghdGhpcy5fbG9vcCAmJiAhdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdGFydFRpbWUgKyBjb21wdXRlZER1cmF0aW9uKTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3Mgbm90IGxvb3BpbmcsIHNldCB0aGUgc3RhdGUgY2hhbmdlIGF0IHRoZSBlbmQgb2YgdGhlIHNhbXBsZVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24sIHtcbiAgICAgICAgICAgICAgICBpbXBsaWNpdEVuZDogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYXJyYXkgb2YgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5hZGQoc291cmNlKTtcbiAgICAgICAgLy8gc3RhcnQgaXRcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgaXNVbmRlZihvcmlnRHVyYXRpb24pKSB7XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzdWJ0cmFjdCB0aGUgZmFkZSBvdXQgdGltZVxuICAgICAgICAgICAgc291cmNlLnN0YXJ0KHN0YXJ0VGltZSwgY29tcHV0ZWRPZmZzZXQsIGNvbXB1dGVkRHVyYXRpb24gLSB0aGlzLnRvU2Vjb25kcyh0aGlzLmZhZGVPdXQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHBsYXliYWNrLlxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgYW5kIHRoZW4gcmVzdGFydCB0aGUgcGxheWVyIGZyb20gdGhlIGJlZ2lubmluZyAob3Igb2Zmc2V0KVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbixcbiAgICAgKiBcdFx0XHRcdFx0aXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqL1xuICAgIHJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VlayB0byBhIHNwZWNpZmljIHRpbWUgaW4gdGhlIHBsYXllcidzIGJ1ZmZlci4gSWYgdGhlXG4gICAgICogc291cmNlIGlzIG5vIGxvbmdlciBwbGF5aW5nIGF0IHRoYXQgdGltZSwgaXQgd2lsbCBzdG9wLlxuICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHRpbWUgdG8gc2VlayB0by5cbiAgICAgKiBAcGFyYW0gd2hlbiBUaGUgdGltZSBmb3IgdGhlIHNlZWsgZXZlbnQgdG8gb2NjdXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9ndXJnbGluZ190aGVyZW1pbl8xLm1wM1wiLCAoKSA9PiB7XG4gICAgICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAgICAgKiBcdC8vIHNlZWsgdG8gdGhlIG9mZnNldCBpbiAxIHNlY29uZCBmcm9tIG5vd1xuICAgICAqIFx0cGxheWVyLnNlZWsoMC40LCBcIisxXCIpO1xuICAgICAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICBzZWVrKG9mZnNldCwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIGN1cnJlbnRseSBwbGF5aW5nLCBzdG9wIGl0XG4gICAgICAgICAgICB0aGlzLl9zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAvLyByZXN0YXJ0IGl0IGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAgICB0aGlzLl9zdGFydChjb21wdXRlZFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsb29wIHN0YXJ0IGFuZCBlbmQuIFdpbGwgb25seSBsb29wIGlmIGxvb3AgaXMgc2V0IHRvIHRydWUuXG4gICAgICogQHBhcmFtIGxvb3BTdGFydCBUaGUgbG9vcCBzdGFydCB0aW1lXG4gICAgICogQHBhcmFtIGxvb3BFbmQgVGhlIGxvb3AgZW5kIHRpbWVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL21hbGV2b2ljZXNfYWEyX0YzLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gbG9vcCBiZXR3ZWVuIHRoZSBnaXZlbiBwb2ludHNcbiAgICAgKiBwbGF5ZXIuc2V0TG9vcFBvaW50cygwLjIsIDAuMyk7XG4gICAgICogcGxheWVyLmxvb3AgPSB0cnVlO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIHNldExvb3BQb2ludHMobG9vcFN0YXJ0LCBsb29wRW5kKSB7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIHN0YXJ0IGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhsb29wU3RhcnQpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHNvdXJjZVxuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgZW5kIGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhsb29wRW5kKSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdldCB0aGUgY3VycmVudCBzb3VyY2VcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIGJlbG9uZ2luZyB0byB0aGUgcGxheWVyLlxuICAgICAqL1xuICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBzaG91bGQgbG9vcCBvbmNlIGl0J3Mgb3Zlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9kcnVtLXNhbXBsZXMvYnJlYWtiZWF0Lm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGxheWVyLmxvb3AgPSB0cnVlO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICAvLyBpZiBubyBjaGFuZ2UsIGRvIG5vdGhpbmdcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgPT09IGxvb3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgLy8gc2V0IHRoZSBsb29wIG9mIGFsbCBvZiB0aGUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wID0gbG9vcDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG5leHQgc3RvcEV2ZW50XG4gICAgICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXROZXh0U3RhdGUoXCJzdG9wcGVkXCIsIHRoaXMubm93KCkpO1xuICAgICAgICAgICAgaWYgKHN0b3BFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdG9wRXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTm9ybWFsIHNwZWVkIGlzIDEuIFRoZSBwaXRjaCB3aWxsIGNoYW5nZSB3aXRoIHRoZSBwbGF5YmFjayByYXRlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZmVtYWxldm9pY2VzX2FhMl9BNS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHBsYXkgYXQgMS80IHNwZWVkXG4gICAgICogcGxheWVyLnBsYXliYWNrUmF0ZSA9IDAuMjU7XG4gICAgICogLy8gcGxheSBhcyBzb29uIGFzIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgc3RvcCBldmVudCBzaW5jZSBpdCdzIGF0IGEgZGlmZmVyZW50IHRpbWUgbm93XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0b3BwZWRcIiwgbm93KTtcbiAgICAgICAgaWYgKHN0b3BFdmVudCAmJiBzdG9wRXZlbnQuaW1wbGljaXRFbmQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdG9wRXZlbnQudGltZSk7XG4gICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5jYW5jZWxTdG9wKCkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNldCBhbGwgdGhlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UucGxheWJhY2tSYXRlLnNldFZhbHVlQXRUaW1lKHJhdGUsIG5vdyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBiZSByZXZlcnNlZFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvY2hpbWVfMS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqIHBsYXllci5yZXZlcnNlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5yZXZlcnNlO1xuICAgIH1cbiAgICBzZXQgcmV2ZXJzZShyZXYpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnJldmVyc2UgPSByZXY7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sb2FkZWQ7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgLy8gZGlzY29ubmVjdCBhbGwgb2YgdGhlIHBsYXllcnNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5jbGVhcigpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFBsYXllci5wcm90b3R5cGUsIFwiZmFkZUluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFBsYXllci5wcm90b3R5cGUsIFwiZmFkZU91dFwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGxheWVyLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi8uLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgUGxheWVyIH0gZnJvbSBcIi4vUGxheWVyXCI7XG4vKipcbiAqIFBsYXllcnMgY29tYmluZXMgbXVsdGlwbGUgW1tQbGF5ZXJdXSBvYmplY3RzLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUGxheWVycyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbGF5ZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiXSwgXCJ1cmxzXCIpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQbGF5ZXJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQbGF5ZXJzIGhhcyBubyBpbnB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29udGFpbmVyIG9mIGFsbCBvZiB0aGUgcGxheWVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGxheWVycyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCJdLCBcInVybHNcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHZvbHVtZSBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgVG9uZUF1ZGlvQnVmZmVycyh7XG4gICAgICAgICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgYmFzZVVybDogb3B0aW9ucy5iYXNlVXJsLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtdXRlIGluaXRpYWxseVxuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiYXNlVXJsOiBcIlwiLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGVudmVsb3BlIGFwcGxpZWQgdG8gdGhlIHNvdXJjZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKGZhZGVJbikge1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBmYWRlSW47XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4ge1xuICAgICAgICAgICAgcGxheWVyLmZhZGVJbiA9IGZhZGVJbjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGVhY2ggb2YgdGhlIHNvdXJjZXMuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dChmYWRlT3V0KSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBmYWRlT3V0O1xuICAgICAgICB0aGlzLl9wbGF5ZXJzLmZvckVhY2gocGxheWVyID0+IHtcbiAgICAgICAgICAgIHBsYXllci5mYWRlT3V0ID0gZmFkZU91dDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0ZSBvZiB0aGUgcGxheWVycyBvYmplY3QuIFJldHVybnMgXCJzdGFydGVkXCIgaWYgYW55IG9mIHRoZSBwbGF5ZXJzIGFyZSBwbGF5aW5nLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgY29uc3QgcGxheWluZyA9IEFycmF5LmZyb20odGhpcy5fcGxheWVycykuc29tZSgoW18sIHBsYXllcl0pID0+IHBsYXllci5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpO1xuICAgICAgICByZXR1cm4gcGxheWluZyA/IFwic3RhcnRlZFwiIDogXCJzdG9wcGVkXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRydWUgaWYgdGhlIGJ1ZmZlcnMgb2JqZWN0IGhhcyBhIGJ1ZmZlciBieSB0aGF0IG5hbWUuXG4gICAgICogQHBhcmFtIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5oYXMobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIHBsYXllciBieSBuYW1lLlxuICAgICAqIEBwYXJhbSAgbmFtZSAgVGhlIHBsYXllcnMgbmFtZSBhcyBkZWZpbmVkIGluIHRoZSBjb25zdHJ1Y3RvciBvYmplY3Qgb3IgYGFkZGAgbWV0aG9kLlxuICAgICAqL1xuICAgIHBsYXllcihuYW1lKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLmhhcyhuYW1lKSwgYE5vIFBsYXllciB3aXRoIHRoZSBuYW1lICR7bmFtZX0gZXhpc3RzIG9uIHRoaXMgb2JqZWN0YCk7XG4gICAgICAgIGlmICghdGhpcy5fcGxheWVycy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHBsYXllciA9IG5ldyBQbGF5ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBmYWRlSW46IHRoaXMuX2ZhZGVJbixcbiAgICAgICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9mYWRlT3V0LFxuICAgICAgICAgICAgICAgIHVybDogdGhpcy5fYnVmZmVycy5nZXQobmFtZSksXG4gICAgICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX3BsYXllcnMuc2V0KG5hbWUsIHBsYXllcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXllcnMuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBhbGwgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5sb2FkZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIHBsYXllciBieSBuYW1lIGFuZCB1cmwgdG8gdGhlIFBsYXllcnNcbiAgICAgKiBAcGFyYW0gIG5hbWUgQSB1bmlxdWUgbmFtZSB0byBnaXZlIHRoZSBwbGF5ZXJcbiAgICAgKiBAcGFyYW0gIHVybCAgRWl0aGVyIHRoZSB1cmwgb2YgdGhlIGJ1ZmVyIG9yIGEgYnVmZmVyIHdoaWNoIHdpbGwgYmUgYWRkZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBhZGQobmFtZSwgdXJsLCBjYWxsYmFjaykge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUpLCBcIkEgYnVmZmVyIHdpdGggdGhhdCBuYW1lIGFscmVhZHkgZXhpc3RzIG9uIHRoaXMgb2JqZWN0XCIpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChuYW1lLCB1cmwsIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgYWxsIG9mIHRoZSBwbGF5ZXJzIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdG8gc3RvcCBhbGwgb2YgdGhlIHBsYXllcnMuXG4gICAgICovXG4gICAgc3RvcEFsbCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4gcGxheWVyLnN0b3AodGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4gcGxheWVyLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbGF5ZXJzLmpzLm1hcCIsImltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQ2xvY2sgfSBmcm9tIFwiLi4vLi4vY29yZS9jbG9jay9DbG9ja1wiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBHcmFpblBsYXllciBpbXBsZW1lbnRzIFtncmFudWxhciBzeW50aGVzaXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0dyYW51bGFyX3N5bnRoZXNpcykuXG4gKiBHcmFudWxhciBTeW50aGVzaXMgZW5hYmxlcyB5b3UgdG8gYWRqdXN0IHBpdGNoIGFuZCBwbGF5YmFjayByYXRlIGluZGVwZW5kZW50bHkuIFRoZSBncmFpblNpemUgaXMgdGhlXG4gKiBhbW91bnQgb2YgdGltZSBlYWNoIHNtYWxsIGNodW5rIG9mIGF1ZGlvIGlzIHBsYXllZCBmb3IgYW5kIHRoZSBvdmVybGFwIGlzIHRoZVxuICogYW1vdW50IG9mIGNyb3NzZmFkaW5nIHRyYW5zaXRpb24gdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZ3JhaW5zLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgR3JhaW5QbGF5ZXIgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmFpblBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyYWluUGxheWVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbnRlcm5hbCBsb29wU3RhcnQgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbnRlcm5hbCBsb29wU3RhcnQgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBjdXJyZW50bHkgcGxheWluZyBCdWZmZXJTb3VyY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmFpblBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcih7XG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxuICAgICAgICAgICAgcmV2ZXJzZTogb3B0aW9ucy5yZXZlcnNlLFxuICAgICAgICAgICAgdXJsOiBvcHRpb25zLnVybCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrID0gbmV3IENsb2NrKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEgLyBvcHRpb25zLmdyYWluU2l6ZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IG9wdGlvbnMuZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLl9vdmVybGFwID0gb3B0aW9ucy5vdmVybGFwO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG9wdGlvbnMuZGV0dW5lO1xuICAgICAgICAvLyBzZXR1cFxuICAgICAgICB0aGlzLm92ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5ncmFpblNpemUgPSBvcHRpb25zLmdyYWluU2l6ZTtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSBvcHRpb25zLnJldmVyc2U7XG4gICAgICAgIHRoaXMuX2Nsb2NrLm9uKFwic3RvcFwiLCB0aGlzLl9vbnN0b3AuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBvdmVybGFwOiAwLjEsXG4gICAgICAgICAgICBncmFpblNpemU6IDAuMixcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdGFydCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIG9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZ3JhaW5TaXplID0gMSAvIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2xvY2suc3RhcnQodGltZSwgb2Zmc2V0IC8gZ3JhaW5TaXplKTtcbiAgICAgICAgaWYgKGR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbmQgdGhlbiByZXN0YXJ0IHRoZSBwbGF5ZXIgZnJvbSB0aGUgYmVnaW5uaW5nIChvciBvZmZzZXQpXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLFxuICAgICAqIFx0XHRcdFx0XHRpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdG9wIG1ldGhvZFxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fY2xvY2suc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCB3aGVuIHRoZSBjbG9jayBpcyBzdG9wcGVkXG4gICAgICovXG4gICAgX29uc3RvcCh0aW1lKSB7XG4gICAgICAgIC8vIHN0b3AgdGhlIHBsYXllcnNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKChzb3VyY2UpID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5mYWRlT3V0ID0gMDtcbiAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vbnN0b3AodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZWQgb24gZWFjaCBjbG9jayB0aWNrLiBzY2hlZHVsZWQgYSBuZXcgZ3JhaW4gYXQgdGhpcyB0aW1lLlxuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQgc2hvdWxkIHN0b3AgbG9vcGluZ1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aWNrcyAqIHRoaXMuX2dyYWluU2l6ZTtcbiAgICAgICAgdGhpcy5sb2coXCJvZmZzZXRcIiwgb2Zmc2V0KTtcbiAgICAgICAgaWYgKCF0aGlzLmxvb3AgJiYgb2Zmc2V0ID4gdGhpcy5idWZmZXIuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlLCB0aGUgZmFkZSBpbiBzaG91bGQgYmUgMFxuICAgICAgICBjb25zdCBmYWRlSW4gPSBvZmZzZXQgPCB0aGlzLl9vdmVybGFwID8gMCA6IHRoaXMuX292ZXJsYXA7XG4gICAgICAgIC8vIGNyZWF0ZSBhIGJ1ZmZlciBzb3VyY2VcbiAgICAgICAgY29uc3Qgc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdXJsOiB0aGlzLmJ1ZmZlcixcbiAgICAgICAgICAgIGZhZGVJbjogZmFkZUluLFxuICAgICAgICAgICAgZmFkZU91dDogdGhpcy5fb3ZlcmxhcCxcbiAgICAgICAgICAgIGxvb3A6IHRoaXMubG9vcCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5fbG9vcFN0YXJ0LFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5fbG9vcEVuZCxcbiAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIHBsYXliYWNrUmF0ZSBiYXNlZCBvbiB0aGUgZGV0dW5lXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyh0aGlzLmRldHVuZSAvIDEwMClcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHNvdXJjZS5zdGFydCh0aW1lLCB0aGlzLl9ncmFpblNpemUgKiB0aWNrcyk7XG4gICAgICAgIHNvdXJjZS5zdG9wKHRpbWUgKyB0aGlzLl9ncmFpblNpemUgLyB0aGlzLnBsYXliYWNrUmF0ZSk7XG4gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5wdXNoKHNvdXJjZSk7XG4gICAgICAgIC8vIHJlbW92ZSBpdCB3aGVuIGl0J3MgZG9uZVxuICAgICAgICBzb3VyY2Uub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWN0aXZlU291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgc2FtcGxlXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHJhdGUsIDAuMDAxKTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5ncmFpblNpemUgPSB0aGlzLl9ncmFpblNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wIHN0YXJ0IHRpbWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wIGVuZCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQodGltZSkge1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRpcmVjdGlvbiB0aGUgYnVmZmVyIHNob3VsZCBwbGF5IGluXG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5yZXZlcnNlO1xuICAgIH1cbiAgICBzZXQgcmV2ZXJzZShyZXYpIHtcbiAgICAgICAgdGhpcy5idWZmZXIucmV2ZXJzZSA9IHJldjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgZWFjaCBjaHVuayBvZiBhdWRpbyB0aGF0IHRoZVxuICAgICAqIGJ1ZmZlciBpcyBjaG9wcGVkIGludG8gYW5kIHBsYXllZCBiYWNrIGF0LlxuICAgICAqL1xuICAgIGdldCBncmFpblNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ncmFpblNpemU7XG4gICAgfVxuICAgIHNldCBncmFpblNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9ncmFpblNpemUgPSB0aGlzLnRvU2Vjb25kcyhzaXplKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKHRoaXMuX3BsYXliYWNrUmF0ZSAvIHRoaXMuX2dyYWluU2l6ZSwgdGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgY3Jvc3MtZmFkZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZ3JhaW5zLlxuICAgICAqL1xuICAgIGdldCBvdmVybGFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3ZlcmxhcDtcbiAgICB9XG4gICAgc2V0IG92ZXJsYXAodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UoY29tcHV0ZWRUaW1lLCAwKTtcbiAgICAgICAgdGhpcy5fb3ZlcmxhcCA9IGNvbXB1dGVkVGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgYWxsIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLmxvYWRlZDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKChzb3VyY2UpID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmFpblBsYXllci5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9Ob2lzZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVXNlck1lZGlhXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL09zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvQU1Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0ZNT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9QdWxzZU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvRmF0T3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9QV01Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9MRk9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvUGxheWVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvUGxheWVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL0dyYWluUGxheWVyXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBSZXR1cm4gdGhlIGFic29sdXRlIHZhbHVlIG9mIGFuIGluY29taW5nIHNpZ25hbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFicyA9IG5ldyBUb25lLkFicygpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDEpO1xuICogXHRzaWduYWwucmFtcFRvKC0xLCAwLjUpO1xuICogXHRzaWduYWwuY29ubmVjdChhYnMpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFicyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBYnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBub2RlIHdoaWNoIGNvbnZlcnRzIHRoZSBhdWRpbyByYW5nZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FicyA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHZhbCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKHZhbCkgPCAwLjAwMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmFicyh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2UgaW5wdXQgWy0xLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2FicztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgcmFuZ2UgWzAsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2FicztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Ficy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFicy5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBHYWluVG9BdWRpbyBjb252ZXJ0cyBhbiBpbnB1dCBpbiBOb3JtYWxSYW5nZSBbMCwxXSB0byBBdWRpb1JhbmdlIFstMSwxXS5cbiAqIFNlZSBbW0F1ZGlvVG9HYWluXV0uXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHYWluVG9BdWRpbyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYWluVG9BdWRpb1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbm9ybSA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHggPT4gTWF0aC5hYnMoeCkgKiAyIC0gMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgTm9ybWFsUmFuZ2UgaW5wdXQgWzAsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbm9ybTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBdWRpb1JhbmdlIG91dHB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX25vcm07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ub3JtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2FpblRvQXVkaW8uanMubWFwIiwiaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBOZWdhdGUgdGhlIGluY29taW5nIHNpZ25hbC4gaS5lLiBhbiBpbnB1dCBzaWduYWwgb2YgMTAgd2lsbCBvdXRwdXQgLTEwXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5lZyA9IG5ldyBUb25lLk5lZ2F0ZSgpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKC0yKS5jb25uZWN0KG5lZyk7XG4gKiAvLyBvdXRwdXQgb2YgbmVnIGlzIHBvc2l0aXZlIDIuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBOZWdhdGUgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTmVnYXRlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBuZWdhdGlvbiBpcyBkb25lIGJ5IG11bHRpcGx5aW5nIGJ5IC0xXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogLTEsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IGFuZCBvdXRwdXQgYXJlIGVxdWFsIHRvIHRoZSBtdWx0aXBseSBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbXVsdGlwbHk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbXVsdGlwbHk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICogQHJldHVybnMge05lZ2F0ZX0gdGhpc1xuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbXVsdGlwbHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1OZWdhdGUuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOZWdhdGUgfSBmcm9tIFwiLi4vc2lnbmFsL05lZ2F0ZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbi8qKlxuICogU3VidHJhY3QgdGhlIHNpZ25hbCBjb25uZWN0ZWQgdG8gdGhlIGlucHV0IGlzIHN1YnRyYWN0ZWQgZnJvbSB0aGUgc2lnbmFsIGNvbm5lY3RlZFxuICogVGhlIHN1YnRyYWhlbmQuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIHN1YnRyYWN0IGEgc2NhbGFyIGZyb20gYSBzaWduYWxcbiAqIGNvbnN0IHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KDEpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3Qoc3ViKTtcbiAqIC8vIHRoZSBvdXRwdXQgb2Ygc3ViIGlzIDMuXG4gKiBAZXhhbXBsZVxuICogLy8gc3VidHJhY3QgdHdvIHNpZ25hbHNcbiAqIGNvbnN0IHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG4gKiBjb25zdCBzaWdBID0gbmV3IFRvbmUuU2lnbmFsKDEwKTtcbiAqIGNvbnN0IHNpZ0IgPSBuZXcgVG9uZS5TaWduYWwoMi41KTtcbiAqIHNpZ0EuY29ubmVjdChzdWIpO1xuICogc2lnQi5jb25uZWN0KHN1Yi5zdWJ0cmFoZW5kKTtcbiAqIC8vIG91dHB1dCBvZiBzdWIgaXMgNy41XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJ0cmFjdCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3VidHJhY3QuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN1YnRyYWN0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc3VtbWluZyBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdW0gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOZWdhdGUgdGhlIGlucHV0IG9mIHRoZSBzZWNvbmQgaW5wdXQgYmVmb3JlIGNvbm5lY3RpbmcgaXQgdG8gdGhlIHN1bW1pbmcgbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25lZyA9IG5ldyBOZWdhdGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgd2hpY2ggaXMgc3VidHJhY3RlZCBmcm9tIHRoZSBtYWluIHNpZ25hbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdWJ0cmFoZW5kID0gdGhpcy5fcGFyYW07XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5fY29uc3RhbnRTb3VyY2UsIHRoaXMuX25lZywgdGhpcy5fc3VtKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25lZy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1bS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN1YnRyYWN0LmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogR3JlYXRlclRoYW5aZXJvIG91dHB1dHMgMSB3aGVuIHRoZSBpbnB1dCBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gemVyb1xuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBndDAgPSBuZXcgVG9uZS5HcmVhdGVyVGhhblplcm8oKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3QoZ3QwKTtcbiAqIFx0c2lnLnNldFZhbHVlQXRUaW1lKC0xLCAwLjA1KTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmVhdGVyVGhhblplcm8gZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JlYXRlclRoYW5aZXJvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHcmVhdGVyVGhhblplcm9cIjtcbiAgICAgICAgdGhpcy5fdGhyZXNoID0gdGhpcy5vdXRwdXQgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDEyNyxcbiAgICAgICAgICAgIG1hcHBpbmc6ICh2YWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsIDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSB0aGlzLmlucHV0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAxMDAwMFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fc2NhbGUuY29ubmVjdCh0aGlzLl90aHJlc2gpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGhyZXNoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JlYXRlclRoYW5aZXJvLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBHcmVhdGVyVGhhblplcm8gfSBmcm9tIFwiLi9HcmVhdGVyVGhhblplcm9cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogT3V0cHV0IDEgaWYgdGhlIHNpZ25hbCBpcyBncmVhdGVyIHRoYW4gdGhlIHZhbHVlLCBvdGhlcndpc2Ugb3V0cHV0cyAwLlxuICogY2FuIGNvbXBhcmUgdHdvIHNpZ25hbHMgb3IgYSBzaWduYWwgYW5kIGEgbnVtYmVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZ3QgPSBuZXcgVG9uZS5HcmVhdGVyVGhhbigyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCg0KS5jb25uZWN0KGd0KTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmVhdGVyVGhhbiBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JlYXRlclRoYW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHcmVhdGVyVGhhblwiO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fc3VidHJhY3QgPSB0aGlzLmlucHV0ID0gbmV3IFN1YnRyYWN0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ndHogPSB0aGlzLm91dHB1dCA9IG5ldyBHcmVhdGVyVGhhblplcm8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuY29tcGFyYXRvciA9IHRoaXMuX3BhcmFtID0gdGhpcy5fc3VidHJhY3Quc3VidHJhaGVuZDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJjb21wYXJhdG9yXCIpO1xuICAgICAgICAvLyBjb25uZWN0XG4gICAgICAgIHRoaXMuX3N1YnRyYWN0LmNvbm5lY3QodGhpcy5fZ3R6KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2d0ei5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1YnRyYWN0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jb21wYXJhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JlYXRlclRoYW4uanMubWFwIiwiaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBQb3cgYXBwbGllcyBhbiBleHBvbmVudCB0byB0aGUgaW5jb21pbmcgc2lnbmFsLiBUaGUgaW5jb21pbmcgc2lnbmFsIG11c3QgYmUgQXVkaW9SYW5nZSBbLTEsIDFdXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBvdyA9IG5ldyBUb25lLlBvdygyKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3QocG93KTtcbiAqIC8vIG91dHB1dCBvZiBwb3cgaXMgMC4yNS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFBvdyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhQb3cuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQb3dcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvdy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB0aGlzLl9leHBGdW5jKG9wdGlvbnMudmFsdWUpLFxuICAgICAgICAgICAgbGVuZ3RoOiA4MTkyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSBvcHRpb25zLnZhbHVlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogdGhlIGZ1bmN0aW9uIHdoaWNoIG1hcHMgdGhlIHdhdmVzaGFwZXJcbiAgICAgKiBAcGFyYW0gZXhwb25lbnQgZXhwb25lbnQgdmFsdWVcbiAgICAgKi9cbiAgICBfZXhwRnVuYyhleHBvbmVudCkge1xuICAgICAgICByZXR1cm4gKHZhbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgucG93KE1hdGguYWJzKHZhbCksIGV4cG9uZW50KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlIG9mIHRoZSBleHBvbmVudC5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9leHBvbmVudDtcbiAgICB9XG4gICAgc2V0IHZhbHVlKGV4cG9uZW50KSB7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50ID0gZXhwb25lbnQ7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50U2NhbGVyLnNldE1hcCh0aGlzLl9leHBGdW5jKHRoaXMuX2V4cG9uZW50KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Qb3cuanMubWFwIiwiaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi9TY2FsZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBQb3cgfSBmcm9tIFwiLi9Qb3dcIjtcbi8qKlxuICogUGVyZm9ybXMgYW4gZXhwb25lbnRpYWwgc2NhbGluZyBvbiBhbiBpbnB1dCBzaWduYWwuXG4gKiBTY2FsZXMgYSBOb3JtYWxSYW5nZSB2YWx1ZSBbMCwxXSBleHBvbmVudGlhbGx5XG4gKiB0byB0aGUgb3V0cHV0IHJhbmdlIG9mIG91dHB1dE1pbiB0byBvdXRwdXRNYXguXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc2NhbGVFeHAgPSBuZXcgVG9uZS5TY2FsZUV4cCgwLCAxMDAsIDIpO1xuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChzY2FsZUV4cCk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2FsZUV4cCBleHRlbmRzIFNjYWxlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZUV4cC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiLCBcImV4cG9uZW50XCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNjYWxlRXhwXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZUV4cC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiLCBcImV4cG9uZW50XCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2V4cCA9IG5ldyBQb3coe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZXhwb25lbnQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9leHAuY29ubmVjdCh0aGlzLl9tdWx0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTY2FsZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBleHBvbmVudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc3RlYWQgb2YgaW50ZXJwb2xhdGluZyBsaW5lYXJseSBiZXR3ZWVuIHRoZSBbW21pbl1dIGFuZFxuICAgICAqIFtbbWF4XV0gdmFsdWVzLCBzZXR0aW5nIHRoZSBleHBvbmVudCB3aWxsIGludGVycG9sYXRlIGJldHdlZW5cbiAgICAgKiB0aGUgdHdvIHZhbHVlcyB3aXRoIGFuIGV4cG9uZW50aWFsIGN1cnZlLlxuICAgICAqL1xuICAgIGdldCBleHBvbmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IGV4cG9uZW50KGV4cCkge1xuICAgICAgICB0aGlzLl9leHAudmFsdWUgPSBleHA7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2NhbGVFeHAuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgVG9uZUNvbnN0YW50U291cmNlIH0gZnJvbSBcIi4vVG9uZUNvbnN0YW50U291cmNlXCI7XG4vKipcbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gc3luY2hyb25pemUgdGhlIHNpZ25hbCB0byB0aGUgW1tUcmFuc3BvcnRdXVxuICovXG5leHBvcnQgY2xhc3MgU3luY2VkU2lnbmFsIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN5bmNlZFNpZ25hbFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogRG9uJ3Qgb3ZlcnJpZGUgd2hlbiBzb21ldGhpbmcgaXMgY29ubmVjdGVkIHRvIHRoZSBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWwgPSBvcHRpb25zLnZhbHVlO1xuICAgICAgICB0aGlzLl9zeW5jZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KHRoaXMuX29uVGljay5iaW5kKHRoaXMpLCBcIjFpXCIpO1xuICAgICAgICB0aGlzLl9zeW5jZWRDYWxsYmFjayA9IHRoaXMuX2FuY2hvclZhbHVlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdG9wXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgLy8gZGlzY29ubmVjdCB0aGUgY29uc3RhbnQgc291cmNlIGZyb20gdGhlIG91dHB1dCBhbmQgcmVwbGFjZSBpdCB3aXRoIGFub3RoZXIgb25lXG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uuc3RvcCgwKTtcbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IG9uZVxuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmVDb25zdGFudFNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgfSkuc3RhcnQoMCk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHdoaWNoIGlzIGludm9rZWQgZXZlcnkgdGljay5cbiAgICAgKi9cbiAgICBfb25UaWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdmFsID0gc3VwZXIuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgLy8gYXBwcm94aW1hdGUgcmFtcCBjdXJ2ZXMgd2l0aCBsaW5lYXIgcmFtcHNcbiAgICAgICAgaWYgKHRoaXMuX2xhc3RWYWwgIT09IHZhbCkge1xuICAgICAgICAgICAgdGhpcy5fbGFzdFZhbCA9IHZhbDtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5zZXRWYWx1ZUF0VGltZSh2YWwsIHRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFuY2hvciB0aGUgdmFsdWUgYXQgdGhlIHN0YXJ0IGFuZCBzdG9wIG9mIHRoZSBUcmFuc3BvcnRcbiAgICAgKi9cbiAgICBfYW5jaG9yVmFsdWUodGltZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzdXBlci5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZykge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBjb21wdXRlZFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmNhbmNlbEFuZEhvbGRBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0UmFtcFBvaW50KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci50YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKHRoaXMuX3N5bmNlZCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdG9wXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TeW5jZWRTaWduYWwuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vQWRkXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BYnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1ZGlvVG9HYWluXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HYWluVG9BdWRpb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vR3JlYXRlclRoYW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dyZWF0ZXJUaGFuWmVyb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL05lZ2F0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUG93XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TaWduYWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NjYWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TY2FsZUV4cFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3VidHJhY3RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N5bmNlZFNpZ25hbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vWmVyb1wiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyLCBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0LCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBjb25uZWN0U2lnbmFsLCBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyByYW5nZSwgdGltZVJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogRW52ZWxvcGUgaXMgYW4gW0FEU1JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpXG4gKiBlbnZlbG9wZSBnZW5lcmF0b3IuIEVudmVsb3BlIG91dHB1dHMgYSBzaWduYWwgd2hpY2hcbiAqIGNhbiBiZSBjb25uZWN0ZWQgdG8gYW4gQXVkaW9QYXJhbSBvciBUb25lLlNpZ25hbC5cbiAqIGBgYFxuICogICAgICAgICAgIC9cXFxuICogICAgICAgICAgLyAgXFxcbiAqICAgICAgICAgLyAgICBcXFxuICogICAgICAgIC8gICAgICBcXFxuICogICAgICAgLyAgICAgICAgXFxfX19fX19fX19fX1xuICogICAgICAvICAgICAgICAgICAgICAgICAgICAgXFxcbiAqICAgICAvICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogICAgLyAgICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogICAvICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gKiBcdFx0YXR0YWNrOiAwLjEsXG4gKiBcdFx0ZGVjYXk6IDAuMixcbiAqIFx0XHRzdXN0YWluOiAwLjUsXG4gKiBcdFx0cmVsZWFzZTogMC44LFxuICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZSgwLjUpO1xuICogfSwgMS41LCAxKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVudmVsb3BlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc2lnbmFsIHdoaWNoIGlzIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NpZyA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBzaWduYWwgb2YgdGhlIGVudmVsb3BlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3NpZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVudmVsb3BlIGhhcyBubyBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSk7XG4gICAgICAgIHRoaXMuYXR0YWNrID0gb3B0aW9ucy5hdHRhY2s7XG4gICAgICAgIHRoaXMuZGVjYXkgPSBvcHRpb25zLmRlY2F5O1xuICAgICAgICB0aGlzLnN1c3RhaW4gPSBvcHRpb25zLnN1c3RhaW47XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcbiAgICAgICAgdGhpcy5hdHRhY2tDdXJ2ZSA9IG9wdGlvbnMuYXR0YWNrQ3VydmU7XG4gICAgICAgIHRoaXMucmVsZWFzZUN1cnZlID0gb3B0aW9ucy5yZWxlYXNlQ3VydmU7XG4gICAgICAgIHRoaXMuZGVjYXlDdXJ2ZSA9IG9wdGlvbnMuZGVjYXlDdXJ2ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgIGF0dGFja0N1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgIGRlY2F5Q3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICByZWxlYXNlQ3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgIHN1c3RhaW46IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGVudmVsb3BlLiBVc2VmdWwgZm9yXG4gICAgICogc3luY2hyb25pemluZyB2aXN1YWwgb3V0cHV0IHRvIHRoZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnZlXG4gICAgICogQHBhcmFtICBjdXJ2ZVxuICAgICAqIEBwYXJhbSAgZGlyZWN0aW9uICBJbi9PdXRcbiAgICAgKiBAcmV0dXJuIFRoZSBjdXJ2ZSBuYW1lXG4gICAgICovXG4gICAgX2dldEN1cnZlKGN1cnZlLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGN1cnZlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgY3VydmVzIGFycmF5XG4gICAgICAgICAgICBsZXQgY3VydmVOYW1lO1xuICAgICAgICAgICAgZm9yIChjdXJ2ZU5hbWUgaW4gRW52ZWxvcGVDdXJ2ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoRW52ZWxvcGVDdXJ2ZXNbY3VydmVOYW1lXVtkaXJlY3Rpb25dID09PSBjdXJ2ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VydmVOYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgY3VzdG9tIGN1cnZlXG4gICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQXNzaWduIGEgdGhlIGN1cnZlIHRvIHRoZSBnaXZlbiBuYW1lIHVzaW5nIHRoZSBkaXJlY3Rpb25cbiAgICAgKiBAcGFyYW0gIG5hbWVcbiAgICAgKiBAcGFyYW0gIGRpcmVjdGlvbiBJbi9PdXRcbiAgICAgKiBAcGFyYW0gIGN1cnZlXG4gICAgICovXG4gICAgX3NldEN1cnZlKG5hbWUsIGRpcmVjdGlvbiwgY3VydmUpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQncyBhIHZhbGlkIHR5cGVcbiAgICAgICAgaWYgKGlzU3RyaW5nKGN1cnZlKSAmJiBSZWZsZWN0LmhhcyhFbnZlbG9wZUN1cnZlcywgY3VydmUpKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJ2ZURlZiA9IEVudmVsb3BlQ3VydmVzW2N1cnZlXTtcbiAgICAgICAgICAgIGlmIChpc09iamVjdChjdXJ2ZURlZikpIHtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSAhPT0gXCJfZGVjYXlDdXJ2ZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZURlZltkaXJlY3Rpb25dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZURlZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0FycmF5KGN1cnZlKSAmJiBuYW1lICE9PSBcIl9kZWNheUN1cnZlXCIpIHtcbiAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVudmVsb3BlOiBpbnZhbGlkIGN1cnZlOiBcIiArIGN1cnZlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIGF0dGFjay5cbiAgICAgKiBDYW4gYmUgYW55IG9mIHRoZXNlIHN0cmluZ3M6XG4gICAgICogKiBcImxpbmVhclwiXG4gICAgICogKiBcImV4cG9uZW50aWFsXCJcbiAgICAgKiAqIFwic2luZVwiXG4gICAgICogKiBcImNvc2luZVwiXG4gICAgICogKiBcImJvdW5jZVwiXG4gICAgICogKiBcInJpcHBsZVwiXG4gICAgICogKiBcInN0ZXBcIlxuICAgICAqXG4gICAgICogQ2FuIGFsc28gYmUgYW4gYXJyYXkgd2hpY2ggZGVzY3JpYmVzIHRoZSBjdXJ2ZS4gVmFsdWVzXG4gICAgICogaW4gdGhlIGFycmF5IGFyZSBldmVubHkgc3ViZGl2aWRlZCBhbmQgbGluZWFybHlcbiAgICAgKiBpbnRlcnBvbGF0ZWQgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIGF0dGFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICAgICAqIFx0Y29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoMC40KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYuYXR0YWNrQ3VydmUgPSBcImxpbmVhclwiO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgYXR0YWNrQ3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDdXJ2ZSh0aGlzLl9hdHRhY2tDdXJ2ZSwgXCJJblwiKTtcbiAgICB9XG4gICAgc2V0IGF0dGFja0N1cnZlKGN1cnZlKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnZlKFwiX2F0dGFja0N1cnZlXCIsIFwiSW5cIiwgY3VydmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIHJlbGVhc2UuIFNlZSB0aGUgYXR0YWNrIGN1cnZlIHR5cGVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gICAgICogXHRcdHJlbGVhc2U6IDAuOFxuICAgICAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiBcdC8vIHJlbGVhc2UgY3VydmUgY291bGQgYWxzbyBiZSBkZWZpbmVkIGJ5IGFuIGFycmF5XG4gICAgICogXHRlbnYucmVsZWFzZUN1cnZlID0gWzEsIDAuMywgMC40LCAwLjIsIDAuNywgMF07XG4gICAgICogXHRlbnYudHJpZ2dlclJlbGVhc2UoMC4yKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgcmVsZWFzZUN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q3VydmUodGhpcy5fcmVsZWFzZUN1cnZlLCBcIk91dFwiKTtcbiAgICB9XG4gICAgc2V0IHJlbGVhc2VDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICB0aGlzLl9zZXRDdXJ2ZShcIl9yZWxlYXNlQ3VydmVcIiwgXCJPdXRcIiwgY3VydmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIGRlY2F5IGVpdGhlciBcImxpbmVhclwiIG9yIFwiZXhwb25lbnRpYWxcIlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gICAgICogXHRcdHN1c3RhaW46IDAuMSxcbiAgICAgKiBcdFx0ZGVjYXk6IDAuNVxuICAgICAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIFx0ZW52LmRlY2F5Q3VydmUgPSBcImxpbmVhclwiO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgZGVjYXlDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY2F5Q3VydmU7XG4gICAgfVxuICAgIHNldCBkZWNheUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIGFzc2VydChbXCJsaW5lYXJcIiwgXCJleHBvbmVudGlhbFwiXS5zb21lKGMgPT4gYyA9PT0gY3VydmUpLCBgSW52YWxpZCBlbnZlbG9wZSBjdXJ2ZTogJHtjdXJ2ZX1gKTtcbiAgICAgICAgdGhpcy5fZGVjYXlDdXJ2ZSA9IGN1cnZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2svZGVjYXkgcG9ydGlvbiBvZiB0aGUgQURTUiBlbnZlbG9wZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZSBzY2FsZXMgdGhlIHZhbGVzLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIgYmV0d2VlbiAwLTFcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSBhdHRhY2sgMC41IHNlY29uZHMgZnJvbSBub3cgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrKFwiKzAuNVwiLCAwLjIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxBdHRhY2sgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjayk7XG4gICAgICAgIGxldCBhdHRhY2sgPSBvcmlnaW5hbEF0dGFjaztcbiAgICAgICAgY29uc3QgZGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KTtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQncyBub3QgYSBjb21wbGV0ZSBhdHRhY2tcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA+IDApIHtcbiAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZSBjdXJyZW50IHZhbHVlIGZyb20gdGhlIGF0dGFjayB0aW1lXG4gICAgICAgICAgICBjb25zdCBhdHRhY2tSYXRlID0gMSAvIGF0dGFjaztcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ0Rpc3RhbmNlID0gMSAtIGN1cnJlbnRWYWx1ZTtcbiAgICAgICAgICAgIC8vIHRoZSBhdHRhY2sgaXMgbm93IHRoZSByZW1haW5pbmcgdGltZVxuICAgICAgICAgICAgYXR0YWNrID0gcmVtYWluaW5nRGlzdGFuY2UgLyBhdHRhY2tSYXRlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF0dGFja1xuICAgICAgICBpZiAoYXR0YWNrIDwgdGhpcy5zYW1wbGVUaW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICAgICAgLy8gY2FzZSB3aGVyZSB0aGUgYXR0YWNrIHRpbWUgaXMgMCBzaG91bGQgc2V0IGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQXRUaW1lKHZlbG9jaXR5LCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9hdHRhY2tDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbyh2ZWxvY2l0eSwgYXR0YWNrLCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9hdHRhY2tDdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcudGFyZ2V0UmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2lnLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgICAgICBsZXQgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZTtcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBjdXJ2ZVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBjdXJ2ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFydGluZyBpbmRleCBpcyBiZXR3ZWVuIHRoZSB0d28gdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKGN1cnZlW2kgLSAxXSA8PSBjdXJyZW50VmFsdWUgJiYgY3VycmVudFZhbHVlIDw9IGN1cnZlW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnZlID0gdGhpcy5fYXR0YWNrQ3VydmUuc2xpY2UoaSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBpbmRleCBpcyB0aGUgY3VycmVudCB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICBjdXJ2ZVswXSA9IGN1cnJlbnRWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQ3VydmVBdFRpbWUoY3VydmUsIHRpbWUsIGF0dGFjaywgdmVsb2NpdHkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGRlY2F5XG4gICAgICAgIGlmIChkZWNheSAmJiB0aGlzLnN1c3RhaW4gPCAxKSB7XG4gICAgICAgICAgICBjb25zdCBkZWNheVZhbHVlID0gdmVsb2NpdHkgKiB0aGlzLnN1c3RhaW47XG4gICAgICAgICAgICBjb25zdCBkZWNheVN0YXJ0ID0gdGltZSArIGF0dGFjaztcbiAgICAgICAgICAgIHRoaXMubG9nKFwiZGVjYXlcIiwgZGVjYXlTdGFydCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fZGVjYXlDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShkZWNheVZhbHVlLCBkZWNheSArIGRlY2F5U3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZShkZWNheVZhbHVlLCBkZWNheVN0YXJ0LCBkZWNheSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoZSByZWxlYXNlIG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZSBzaG91bGQgc3RhcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKHtcbiAgICAgKiBcdHR5cGU6IFwic2F3dG9vdGhcIlxuICAgICAqIH0pLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSBoYWxmIGEgc2Vjb25kIGFmdGVyIHRoZSBhdHRhY2tcbiAgICAgKiBlbnYudHJpZ2dlclJlbGVhc2UoXCIrMC41XCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCB0aW1lKTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcmVsZWFzZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMucmVsZWFzZSk7XG4gICAgICAgICAgICBpZiAocmVsZWFzZSA8IHRoaXMuc2FtcGxlVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlbGVhc2VDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5saW5lYXJSYW1wVG8oMCwgcmVsZWFzZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWxlYXNlQ3VydmUgPT09IFwiZXhwb25lbnRpYWxcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8oMCwgcmVsZWFzZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQoaXNBcnJheSh0aGlzLl9yZWxlYXNlQ3VydmUpLCBcInJlbGVhc2VDdXJ2ZSBtdXN0IGJlIGVpdGhlciAnbGluZWFyJywgJ2V4cG9uZW50aWFsJyBvciBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZSh0aGlzLl9yZWxlYXNlQ3VydmUsIHRpbWUsIHJlbGVhc2UsIGN1cnJlbnRWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgc2NoZWR1bGVkIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLiBUaGlzIHdpbGxcbiAgICAgKiByZXR1cm4gdGhlIHVuY29udmVydGVkIChyYXcpIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoMC41LCAxLCAwLjQsIDIpO1xuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZSgyKTtcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhlbnYuZ2V0VmFsdWVBdFRpbWUoVG9uZS5ub3coKSkpLCAxMDApO1xuICAgICAqL1xuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogdHJpZ2dlckF0dGFja1JlbGVhc2UgaXMgc2hvcnRoYW5kIGZvciB0cmlnZ2VyQXR0YWNrLCB0aGVuIHdhaXRpbmdcbiAgICAgKiBzb21lIGR1cmF0aW9uLCB0aGVuIHRyaWdnZXJSZWxlYXNlLlxuICAgICAqIEBwYXJhbSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHN1c3RhaW4uXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSAwLjUgc2Vjb25kcyBhZnRlciB0aGUgYXR0YWNrXG4gICAgICogZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuNSk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UodGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIGFsbCBzY2hlZHVsZWQgZW52ZWxvcGUgY2hhbmdlcyBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5fc2lnLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLnRvU2Vjb25kcyhhZnRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgZW52ZWxvcGUgdG8gYSBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqL1xuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciB0aGUgZW52ZWxvcGUgY3VydmUgdG8gYW4gYXJyYXkgb2YgdGhlIGdpdmVuIGxlbmd0aC5cbiAgICAgKiBHb29kIGZvciB2aXN1YWxpemluZyB0aGUgZW52ZWxvcGUgY3VydmUuIFJlc2NhbGVzIHRoZSBkdXJhdGlvbiBvZiB0aGVcbiAgICAgKiBlbnZlbG9wZSB0byBmaXQgdGhlIGxlbmd0aC5cbiAgICAgKi9cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uID0gbGVuZ3RoIC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDEsIGR1cmF0aW9uLCB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyBub3JtYWxpemUgdGhlIEFEU1IgZm9yIHRoZSBnaXZlbiBkdXJhdGlvbiB3aXRoIDIwJSBzdXN0YWluIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGF0dGFja1BvcnRpb24gPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KTtcbiAgICAgICAgICAgIGNvbnN0IGVudmVsb3BlRHVyYXRpb24gPSBhdHRhY2tQb3J0aW9uICsgdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKTtcbiAgICAgICAgICAgIGNvbnN0IHN1c3RhaW5UaW1lID0gZW52ZWxvcGVEdXJhdGlvbiAqIDAuMTtcbiAgICAgICAgICAgIGNvbnN0IHRvdGFsRHVyYXRpb24gPSBlbnZlbG9wZUR1cmF0aW9uICsgc3VzdGFpblRpbWU7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBjbG9uZSA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKE9iamVjdC5hc3NpZ24odGhpcy5nZXQoKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogZHVyYXRpb24gKiB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjaykgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGRlY2F5OiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpIC8gdG90YWxEdXJhdGlvbixcbiAgICAgICAgICAgICAgICByZWxlYXNlOiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMucmVsZWFzZSkgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGNsb25lLl9zaWcudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICAgICAgY2xvbmUudHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24gKiAoYXR0YWNrUG9ydGlvbiArIHN1c3RhaW5UaW1lKSAvIHRvdGFsRHVyYXRpb24sIDApO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgICAgIHJldHVybiBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgRW52ZWxvcGUucHJvdG90eXBlLCBcImF0dGFja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwiZGVjYXlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHJhbmdlKDAsIDEpXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwic3VzdGFpblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwicmVsZWFzZVwiLCB2b2lkIDApO1xuLyoqXG4gKiBHZW5lcmF0ZSBzb21lIGNvbXBsZXggZW52ZWxvcGUgY3VydmVzLlxuICovXG5jb25zdCBFbnZlbG9wZUN1cnZlcyA9ICgoKSA9PiB7XG4gICAgY29uc3QgY3VydmVMZW4gPSAxMjg7XG4gICAgbGV0IGk7XG4gICAgbGV0IGs7XG4gICAgLy8gY29zaW5lIGN1cnZlXG4gICAgY29uc3QgY29zaW5lQ3VydmUgPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBjb3NpbmVDdXJ2ZVtpXSA9IE1hdGguc2luKChpIC8gKGN1cnZlTGVuIC0gMSkpICogKE1hdGguUEkgLyAyKSk7XG4gICAgfVxuICAgIC8vIHJpcHBsZSBjdXJ2ZVxuICAgIGNvbnN0IHJpcHBsZUN1cnZlID0gW107XG4gICAgY29uc3QgcmlwcGxlQ3VydmVGcmVxID0gNi40O1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbiAtIDE7IGkrKykge1xuICAgICAgICBrID0gKGkgLyAoY3VydmVMZW4gLSAxKSk7XG4gICAgICAgIGNvbnN0IHNpbmVXYXZlID0gTWF0aC5zaW4oayAqIChNYXRoLlBJICogMikgKiByaXBwbGVDdXJ2ZUZyZXEgLSBNYXRoLlBJIC8gMikgKyAxO1xuICAgICAgICByaXBwbGVDdXJ2ZVtpXSA9IHNpbmVXYXZlIC8gMTAgKyBrICogMC44MztcbiAgICB9XG4gICAgcmlwcGxlQ3VydmVbY3VydmVMZW4gLSAxXSA9IDE7XG4gICAgLy8gc3RhaXJzIGN1cnZlXG4gICAgY29uc3Qgc3RhaXJzQ3VydmUgPSBbXTtcbiAgICBjb25zdCBzdGVwcyA9IDU7XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgc3RhaXJzQ3VydmVbaV0gPSBNYXRoLmNlaWwoKGkgLyAoY3VydmVMZW4gLSAxKSkgKiBzdGVwcykgLyBzdGVwcztcbiAgICB9XG4gICAgLy8gaW4tb3V0IGVhc2luZyBjdXJ2ZVxuICAgIGNvbnN0IHNpbmVDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG4gICAgICAgIHNpbmVDdXJ2ZVtpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIGspKTtcbiAgICB9XG4gICAgLy8gYSBib3VuY2UgY3VydmVcbiAgICBjb25zdCBib3VuY2VDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG4gICAgICAgIGNvbnN0IGZyZXEgPSBNYXRoLnBvdyhrLCAzKSAqIDQgKyAwLjI7XG4gICAgICAgIGNvbnN0IHZhbCA9IE1hdGguY29zKGZyZXEgKiBNYXRoLlBJICogMiAqIGspO1xuICAgICAgICBib3VuY2VDdXJ2ZVtpXSA9IE1hdGguYWJzKHZhbCAqICgxIC0gaykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZlcnQgYSB2YWx1ZSBjdXJ2ZSB0byBtYWtlIGl0IHdvcmsgZm9yIHRoZSByZWxlYXNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW52ZXJ0Q3VydmUoY3VydmUpIHtcbiAgICAgICAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KGN1cnZlLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY3VydmUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIG91dFtqXSA9IDEgLSBjdXJ2ZVtqXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiByZXZlcnNlIHRoZSBjdXJ2ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJldmVyc2VDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICByZXR1cm4gY3VydmUuc2xpY2UoMCkucmV2ZXJzZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBhdHRhY2sgYW5kIHJlbGVhc2UgY3VydmUgYXJyYXlzXG4gICAgICovXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYm91bmNlOiB7XG4gICAgICAgICAgICBJbjogaW52ZXJ0Q3VydmUoYm91bmNlQ3VydmUpLFxuICAgICAgICAgICAgT3V0OiBib3VuY2VDdXJ2ZSxcbiAgICAgICAgfSxcbiAgICAgICAgY29zaW5lOiB7XG4gICAgICAgICAgICBJbjogY29zaW5lQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IHJldmVyc2VDdXJ2ZShjb3NpbmVDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgICAgIGV4cG9uZW50aWFsOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgIGxpbmVhcjogXCJsaW5lYXJcIixcbiAgICAgICAgcmlwcGxlOiB7XG4gICAgICAgICAgICBJbjogcmlwcGxlQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHJpcHBsZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgc2luZToge1xuICAgICAgICAgICAgSW46IHNpbmVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUoc2luZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RlcDoge1xuICAgICAgICAgICAgSW46IHN0YWlyc0N1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzdGFpcnNDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgfTtcbn0pKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FbnZlbG9wZS5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZS1jbGFzcyBmb3IgYWxsIGluc3RydW1lbnRzXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnN0cnVtZW50IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBldmVudHMgc2NoZWR1bGVkIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICogd2hlbiB0aGUgaW5zdHJ1bWVudCBpcyAnc3luY2VkJ1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgaW5zdHJ1bWVudCBpcyBjdXJyZW50bHkgc3luY2VkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fb3JpZ2luYWxfdHJpZ2dlckF0dGFjayA9IHRoaXMudHJpZ2dlckF0dGFjaztcbiAgICAgICAgdGhpcy5fb3JpZ2luYWxfdHJpZ2dlclJlbGVhc2UgPSB0aGlzLnRyaWdnZXJSZWxlYXNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBpbnN0cnVtZW50IHRvIHRoZSBUcmFuc3BvcnQuIEFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mXG4gICAgICogW1t0cmlnZ2VyQXR0YWNrXV0gYW5kIFtbdHJpZ2dlclJlbGVhc2VdXSB3aWxsIGJlIHNjaGVkdWxlZCBhbG9uZyB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZm1TeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogZm1TeW50aC52b2x1bWUudmFsdWUgPSAtNjtcbiAgICAgKiBmbVN5bnRoLnN5bmMoKTtcbiAgICAgKiAvLyBzY2hlZHVsZSAzIG5vdGVzIHdoZW4gdGhlIHRyYW5zcG9ydCBmaXJzdCBzdGFydHNcbiAgICAgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiLCAwKTtcbiAgICAgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRTRcIiwgXCI4blwiLCBcIjhuXCIpO1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJHNFwiLCBcIjhuXCIsIFwiNG5cIik7XG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydCB0byBoZWFyIHRoZSBub3Rlc1xuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogc2V0IF9zeW5jXG4gICAgICovXG4gICAgX3N5bmNTdGF0ZSgpIHtcbiAgICAgICAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZCA9IHRydWU7XG4gICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hhbmdlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JhcCB0aGUgZ2l2ZW4gbWV0aG9kIHNvIHRoYXQgaXQgY2FuIGJlIHN5bmNocm9uaXplZFxuICAgICAqIEBwYXJhbSBtZXRob2QgV2hpY2ggbWV0aG9kIHRvIHdyYXAgYW5kIHN5bmNcbiAgICAgKiBAcGFyYW0gIHRpbWVQb3NpdGlvbiBXaGF0IHBvc2l0aW9uIHRoZSB0aW1lIGFyZ3VtZW50IGFwcGVhcnMgaW5cbiAgICAgKi9cbiAgICBfc3luY01ldGhvZChtZXRob2QsIHRpbWVQb3NpdGlvbikge1xuICAgICAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IHRoaXNbXCJfb3JpZ2luYWxfXCIgKyBtZXRob2RdID0gdGhpc1ttZXRob2RdO1xuICAgICAgICB0aGlzW21ldGhvZF0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGltZSA9IGFyZ3NbdGltZVBvc2l0aW9uXTtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSgodCkgPT4ge1xuICAgICAgICAgICAgICAgIGFyZ3NbdGltZVBvc2l0aW9uXSA9IHQ7XG4gICAgICAgICAgICAgICAgb3JpZ2luYWxNZXRob2QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICB9LCB0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5wdXNoKGlkKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBpbnN0cnVtZW50IGZyb20gdGhlIFRyYW5zcG9ydFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzLmZvckVhY2goaWQgPT4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihpZCkpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sgPSB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJSZWxlYXNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHRoZW4gdGhlIHJlbGVhc2UgYWZ0ZXIgdGhlIGR1cmF0aW9uLlxuICAgICAqIEBwYXJhbSAgbm90ZSAgICAgVGhlIG5vdGUgdG8gdHJpZ2dlci5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBub3RlIHNob3VsZCBiZSBoZWxkIGZvciBiZWZvcmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyaW5nIHRoZSByZWxlYXNlLiBUaGlzIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAuXG4gICAgICogQHBhcmFtIHRpbWUgIFdoZW4gdGhlIG5vdGUgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkIGF0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIFwiQzRcIiBmb3IgdGhlIGR1cmF0aW9uIG9mIGFuIDh0aCBub3RlXG4gICAgICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGUsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKiBAcmV0dXJucyB7SW5zdHJ1bWVudH0gdGhpc1xuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUluc3RydW1lbnQuanMubWFwIiwiaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBvdGhlciBtb25vcGhvbmljIGluc3RydW1lbnRzIHRvIGV4dGVuZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm9waG9uaWMgZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5wb3J0YW1lbnRvID0gb3B0aW9ucy5wb3J0YW1lbnRvO1xuICAgICAgICB0aGlzLm9uc2lsZW5jZSA9IG9wdGlvbnMub25zaWxlbmNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgb25zaWxlbmNlOiBub09wLFxuICAgICAgICAgICAgcG9ydGFtZW50bzogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBvZiB0aGUgbm90ZSBvcHRpb25hbGx5IHdpdGggYSBnaXZlbiB2ZWxvY2l0eS5cbiAgICAgKiBAcGFyYW0gIG5vdGUgVGhlIG5vdGUgdG8gdHJpZ2dlci5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgbm90ZSBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgc2NhbGVyIGRldGVybWluZXMgaG93IFwibG91ZFwiIHRoZSBub3RlIHdpbGwgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSBub3RlIGEgaGFsZiBzZWNvbmQgZnJvbSBub3cgYXQgaGFsZiB2ZWxvY2l0eVxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soXCJDNFwiLCBcIiswLjVcIiwgMC41KTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZSwgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayhzZWNvbmRzLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuc2V0Tm90ZShub3RlLCBzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gIHRpbWUgSWYgbm8gdGltZSBpcyBnaXZlbiwgdGhlIHJlbGVhc2UgaGFwcGVucyBpbW1lZGlhdGx5XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soXCJDNFwiKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIGEgc2Vjb25kIGZyb20gbm93XG4gICAgICogc3ludGgudHJpZ2dlclJlbGVhc2UoXCIrMVwiKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlclJlbGVhc2VcIiwgdGltZSk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZShzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbm90ZSBhdCB0aGUgZ2l2ZW4gdGltZS4gSWYgbm8gdGltZSBpcyBnaXZlbiwgdGhlIG5vdGVcbiAgICAgKiB3aWxsIHNldCBpbW1lZGlhdGVseS5cbiAgICAgKiBAcGFyYW0gbm90ZSBUaGUgbm90ZSB0byBjaGFuZ2UgdG8uXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIG5vdGUgc2hvdWxkIGJlIHNldC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuICAgICAqIC8vIGNoYW5nZSB0byBGIzYgaW4gb25lIHF1YXJ0ZXIgbm90ZSBmcm9tIG5vdy5cbiAgICAgKiBzeW50aC5zZXROb3RlKFwiRiM2XCIsIFwiKzRuXCIpO1xuICAgICAqL1xuICAgIHNldE5vdGUobm90ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRGcmVxdWVuY3kgPSBub3RlIGluc3RhbmNlb2YgRnJlcXVlbmN5Q2xhc3MgPyBub3RlLnRvRnJlcXVlbmN5KCkgOiBub3RlO1xuICAgICAgICBpZiAodGhpcy5wb3J0YW1lbnRvID4gMCAmJiB0aGlzLmdldExldmVsQXRUaW1lKGNvbXB1dGVkVGltZSkgPiAwLjA1KSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0VGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMucG9ydGFtZW50byk7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUbyhjb21wdXRlZEZyZXF1ZW5jeSwgcG9ydFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShjb21wdXRlZEZyZXF1ZW5jeSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIE1vbm9waG9uaWMucHJvdG90eXBlLCBcInBvcnRhbWVudG9cIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vbm9waG9uaWMuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuL0VudmVsb3BlXCI7XG4vKipcbiAqIEFtcGxpdHVkZUVudmVsb3BlIGlzIGEgVG9uZS5FbnZlbG9wZSBjb25uZWN0ZWQgdG8gYSBnYWluIG5vZGUuXG4gKiBVbmxpa2UgVG9uZS5FbnZlbG9wZSwgd2hpY2ggb3V0cHV0cyB0aGUgZW52ZWxvcGUncyB2YWx1ZSwgQW1wbGl0dWRlRW52ZWxvcGUgYWNjZXB0c1xuICogYW4gYXVkaW8gc2lnbmFsIGFzIHRoZSBpbnB1dCBhbmQgd2lsbCBhcHBseSB0aGUgZW52ZWxvcGUgdG8gdGhlIGFtcGxpdHVkZVxuICogb2YgdGhlIHNpZ25hbC5cbiAqIFJlYWQgbW9yZSBhYm91dCBBRFNSIEVudmVsb3BlcyBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW50aGVzaXplciNBRFNSX2VudmVsb3BlKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFtcEVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKHtcbiAqIFx0XHRhdHRhY2s6IDAuMSxcbiAqIFx0XHRkZWNheTogMC4yLFxuICogXHRcdHN1c3RhaW46IDEuMCxcbiAqIFx0XHRyZWxlYXNlOiAwLjhcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBjcmVhdGUgYW4gb3NjaWxsYXRvciBhbmQgY29ubmVjdCBpdFxuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhbXBFbnYpLnN0YXJ0KCk7XG4gKiBcdC8vIHRyaWdnZXIgdGhlIGVudmVsb3BlcyBhdHRhY2sgYW5kIHJlbGVhc2UgXCI4dFwiIGFwYXJ0XG4gKiBcdGFtcEVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIjh0XCIpO1xuICogfSwgMS41LCAxKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFtcGxpdHVkZUVudmVsb3BlIGV4dGVuZHMgRW52ZWxvcGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBbXBsaXR1ZGVFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBbXBsaXR1ZGVFbnZlbG9wZVwiO1xuICAgICAgICB0aGlzLl9nYWluTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuX3NpZy5jb25uZWN0KHRoaXMuX2dhaW5Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFtcGxpdHVkZUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG4vKipcbiAqIFN5bnRoIGlzIGNvbXBvc2VkIHNpbXBseSBvZiBhIFtbT21uaU9zY2lsbGF0b3JdXSByb3V0ZWQgdGhyb3VnaCBhbiBbW0FtcGxpdHVkZUVudmVsb3BlXV0uXG4gKiBgYGBcbiAqICstLS0tLS0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCBPbW5pT3NjaWxsYXRvciArPi0tPiBBbXBsaXR1ZGVFbnZlbG9wZSArPi0tPiBPdXRwdXRcbiAqICstLS0tLS0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gbmV3IE9tbmlPc2NpbGxhdG9yKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcyksXG4gICAgICAgIH0sIG9wdGlvbnMub3NjaWxsYXRvcikpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5vc2NpbGxhdG9yLmRldHVuZTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5lbnZlbG9wZSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJlbnZlbG9wZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBbLi4uT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRyaWFuZ2xlXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSB0aGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUgKDAtMSlcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIHRoZSBlbnZlbG9wZXNcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyByZWxlYXNlIHBvcnRpb24sIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRBdHRhY2sgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjayk7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZERlY2F5ID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSk7XG4gICAgICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgY29tcHV0ZWRBdHRhY2sgKyBjb21wdXRlZERlY2F5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSByZWxlYXNlIHNob3VsZCBzdGFydFxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3ludGguanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgT21uaU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGJvdGggQU0gYW5kIEZNIHN5bnRoc1xuICovXG5leHBvcnQgY2xhc3MgTW9kdWxhdGlvblN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb2R1bGF0aW9uU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IFN5bnRoKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IG9wdGlvbnMub3NjaWxsYXRvcixcbiAgICAgICAgICAgIGVudmVsb3BlOiBvcHRpb25zLmVudmVsb3BlLFxuICAgICAgICAgICAgb25zaWxlbmNlOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgICAgIHZvbHVtZTogLTEwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IFN5bnRoKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IG9wdGlvbnMubW9kdWxhdGlvbixcbiAgICAgICAgICAgIGVudmVsb3BlOiBvcHRpb25zLm1vZHVsYXRpb25FbnZlbG9wZSxcbiAgICAgICAgICAgIHZvbHVtZTogLTEwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gdGhpcy5fY2Fycmllci5vc2NpbGxhdG9yO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gdGhpcy5fY2Fycmllci5lbnZlbG9wZTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uID0gdGhpcy5fbW9kdWxhdG9yLm9zY2lsbGF0b3I7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkVudmVsb3BlID0gdGhpcy5fbW9kdWxhdG9yLmVudmVsb3BlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiaGFybW9uaWNpdHlcIiwgXCJvc2NpbGxhdG9yXCIsIFwiZW52ZWxvcGVcIiwgXCJtb2R1bGF0aW9uXCIsIFwibW9kdWxhdGlvbkVudmVsb3BlXCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAzLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBbXG4gICAgICAgICAgICAgICAgLi4uT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpLFxuICAgICAgICAgICAgICAgIFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICAgICAgXCJkZXR1bmVcIlxuICAgICAgICAgICAgXSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNpbmVcIlxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4wMSxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtb2R1bGF0aW9uOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFtcbiAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksXG4gICAgICAgICAgICAgICAgXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgICAgICBcImRldHVuZVwiXG4gICAgICAgICAgICBdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic3F1YXJlXCJcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NhcnJpZXIuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb2R1bGF0aW9uU3ludGguanMubWFwIiwiaW1wb3J0IHsgQXVkaW9Ub0dhaW4gfSBmcm9tIFwiLi4vc2lnbmFsL0F1ZGlvVG9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1vZHVsYXRpb25TeW50aCB9IGZyb20gXCIuL01vZHVsYXRpb25TeW50aFwiO1xuLyoqXG4gKiBBTVN5bnRoIHVzZXMgdGhlIG91dHB1dCBvZiBvbmUgVG9uZS5TeW50aCB0byBtb2R1bGF0ZSB0aGVcbiAqIGFtcGxpdHVkZSBvZiBhbm90aGVyIFRvbmUuU3ludGguIFRoZSBoYXJtb25pY2l0eSAodGhlIHJhdGlvIGJldHdlZW5cbiAqIHRoZSB0d28gc2lnbmFscykgYWZmZWN0cyB0aGUgdGltYnJlIG9mIHRoZSBvdXRwdXQgc2lnbmFsIGdyZWF0bHkuXG4gKiBSZWFkIG1vcmUgYWJvdXQgQW1wbGl0dWRlIE1vZHVsYXRpb24gU3ludGhlc2lzIG9uXG4gKiBbU291bmRPblNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDQxMDM2NTMvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tOjgwL3Nvcy9tYXIwMC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5BTVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjRuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBTVN5bnRoIGV4dGVuZHMgTW9kdWxhdGlvblN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQU1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBTVN5bnRoXCI7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZSA9IG5ldyBBdWRpb1RvR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLl9jYXJyaWVyLmRldHVuZSwgdGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uU2NhbGUsIHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNoYWluKHRoaXMuX21vZHVsYXRpb25Ob2RlLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QU1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBUaGluIHdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgV2ViIEF1ZGlvIFtCaXF1YWRGaWx0ZXJOb2RlXShodHRwczovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNiaXF1YWRmaWx0ZXJub2RlKS5cbiAqIEJpcXVhZEZpbHRlciBpcyBzaW1pbGFyIHRvIFtbRmlsdGVyXV0gYnV0IGRvZXNuJ3QgaGF2ZSB0aGUgb3B0aW9uIHRvIHNldCB0aGUgXCJyb2xsb2ZmXCIgdmFsdWUuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBCaXF1YWRGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQmlxdWFkRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkJpcXVhZEZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQmlxdWFkRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fZmlsdGVyO1xuICAgICAgICB0aGlzLlEgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5nYWluLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5nYWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAzNTAsXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhpcyBCaXF1YWRGaWx0ZXJOb2RlLiBGb3IgYSBjb21wbGV0ZSBsaXN0IG9mIHR5cGVzIGFuZCB0aGVpciBhdHRyaWJ1dGVzLCBzZWUgdGhlXG4gICAgICogW1dlYiBBdWRpbyBBUEldKGh0dHBzOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2RvbS1iaXF1YWRmaWx0ZXJ0eXBlLWxvd3Bhc3MpXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFtcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLCBcImJhbmRwYXNzXCIsXG4gICAgICAgICAgICBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIFwicGVha2luZ1wiXTtcbiAgICAgICAgYXNzZXJ0KHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xLCBgSW52YWxpZCBmaWx0ZXIgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl9maWx0ZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIC8vIHN0YXJ0IHdpdGggYWxsIDFzXG4gICAgICAgIGNvbnN0IGZyZXFWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm0gPSBNYXRoLnBvdyhpIC8gbGVuLCAyKTtcbiAgICAgICAgICAgIGNvbnN0IGZyZXEgPSBub3JtICogKDIwMDAwIC0gMjApICsgMjA7XG4gICAgICAgICAgICBmcmVxVmFsdWVzW2ldID0gZnJlcTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYWdWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGNvbnN0IHBoYXNlVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICAvLyBjbG9uZSB0aGUgZmlsdGVyIHRvIHJlbW92ZSBhbnkgY29ubmVjdGlvbnMgd2hpY2ggbWF5IGJlIGNoYW5naW5nIHRoZSB2YWx1ZVxuICAgICAgICBjb25zdCBmaWx0ZXJDbG9uZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgZmlsdGVyQ2xvbmUudHlwZSA9IHRoaXMudHlwZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuUS52YWx1ZSA9IHRoaXMuUS52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZnJlcXVlbmN5LnZhbHVlID0gdGhpcy5mcmVxdWVuY3kudmFsdWU7XG4gICAgICAgIGZpbHRlckNsb25lLmdhaW4udmFsdWUgPSB0aGlzLmdhaW4udmFsdWU7XG4gICAgICAgIGZpbHRlckNsb25lLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXFWYWx1ZXMsIG1hZ1ZhbHVlcywgcGhhc2VWYWx1ZXMpO1xuICAgICAgICByZXR1cm4gbWFnVmFsdWVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CaXF1YWRGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNOdW1iZXIgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEJpcXVhZEZpbHRlciB9IGZyb20gXCIuL0JpcXVhZEZpbHRlclwiO1xuLyoqXG4gKiBUb25lLkZpbHRlciBpcyBhIGZpbHRlciB3aGljaCBhbGxvd3MgZm9yIGFsbCBvZiB0aGUgc2FtZSBuYXRpdmUgbWV0aG9kc1xuICogYXMgdGhlIFtCaXF1YWRGaWx0ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1iaXF1YWRmaWx0ZXJub2RlLWludGVyZmFjZSkuXG4gKiBUb25lLkZpbHRlciBoYXMgdGhlIGFkZGVkIGFiaWxpdHkgdG8gc2V0IHRoZSBmaWx0ZXIgcm9sbG9mZiBhdCAtMTJcbiAqIChkZWZhdWx0KSwgLTI0IGFuZCAtNDguXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuRmlsdGVyKDE1MDAsIFwiaGlnaHBhc3NcIikudG9EZXN0aW5hdGlvbigpO1xuICogZmlsdGVyLmZyZXF1ZW5jeS5yYW1wVG8oMjAwMDAsIDEwKTtcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5jb25uZWN0KGZpbHRlcikuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwicm9sbG9mZlwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZpbHRlclwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJyb2xsb2ZmXCJdKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IFtdO1xuICAgICAgICB0aGlzLlEgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdhaW4gPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLnJvbGxvZmYgPSBvcHRpb25zLnJvbGxvZmY7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImRldHVuZVwiLCBcImZyZXF1ZW5jeVwiLCBcImdhaW5cIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmaWx0ZXIuIFR5cGVzOiBcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLFxuICAgICAqIFwiYmFuZHBhc3NcIiwgXCJsb3dzaGVsZlwiLCBcImhpZ2hzaGVsZlwiLCBcIm5vdGNoXCIsIFwiYWxscGFzc1wiLCBvciBcInBlYWtpbmdcIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBbXCJsb3dwYXNzXCIsIFwiaGlnaHBhc3NcIiwgXCJiYW5kcGFzc1wiLFxuICAgICAgICAgICAgXCJsb3dzaGVsZlwiLCBcImhpZ2hzaGVsZlwiLCBcIm5vdGNoXCIsIFwiYWxscGFzc1wiLCBcInBlYWtpbmdcIl07XG4gICAgICAgIGFzc2VydCh0eXBlcy5pbmRleE9mKHR5cGUpICE9PSAtMSwgYEludmFsaWQgZmlsdGVyIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4gZmlsdGVyLnR5cGUgPSB0eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHJvbGxvZmYgb2YgdGhlIGZpbHRlciB3aGljaCBpcyB0aGUgZHJvcCBpbiBkYlxuICAgICAqIHBlciBvY3RhdmUuIEltcGxlbWVudGVkIGludGVybmFsbHkgYnkgY2FzY2FkaW5nIGZpbHRlcnMuXG4gICAgICogT25seSBhY2NlcHRzIHRoZSB2YWx1ZXMgLTEyLCAtMjQsIC00OCBhbmQgLTk2LlxuICAgICAqL1xuICAgIGdldCByb2xsb2ZmKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm9sbG9mZjtcbiAgICB9XG4gICAgc2V0IHJvbGxvZmYocm9sbG9mZikge1xuICAgICAgICBjb25zdCByb2xsb2ZmTnVtID0gaXNOdW1iZXIocm9sbG9mZikgPyByb2xsb2ZmIDogcGFyc2VJbnQocm9sbG9mZiwgMTApO1xuICAgICAgICBjb25zdCBwb3NzaWJpbGl0aWVzID0gWy0xMiwgLTI0LCAtNDgsIC05Nl07XG4gICAgICAgIGxldCBjYXNjYWRpbmdDb3VudCA9IHBvc3NpYmlsaXRpZXMuaW5kZXhPZihyb2xsb2ZmTnVtKTtcbiAgICAgICAgLy8gY2hlY2sgdGhlIHJvbGxvZmYgaXMgdmFsaWRcbiAgICAgICAgYXNzZXJ0KGNhc2NhZGluZ0NvdW50ICE9PSAtMSwgYHJvbGxvZmYgY2FuIG9ubHkgYmUgJHtwb3NzaWJpbGl0aWVzLmpvaW4oXCIsIFwiKX1gKTtcbiAgICAgICAgY2FzY2FkaW5nQ291bnQgKz0gMTtcbiAgICAgICAgdGhpcy5fcm9sbG9mZiA9IHJvbGxvZmZOdW07XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IGZpbHRlci5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gbmV3IEFycmF5KGNhc2NhZGluZ0NvdW50KTtcbiAgICAgICAgZm9yIChsZXQgY291bnQgPSAwOyBjb3VudCA8IGNhc2NhZGluZ0NvdW50OyBjb3VudCsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBuZXcgQmlxdWFkRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbHRlci50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QoZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KGZpbHRlci5kZXR1bmUpO1xuICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuICAgICAgICAgICAgdGhpcy5nYWluLmNvbm5lY3QoZmlsdGVyLmdhaW4pO1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyc1tjb3VudF0gPSBmaWx0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IHRoaXMuX2ZpbHRlcnM7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5faW50ZXJuYWxDaGFubmVscywgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZS4gVGhpcyBjdXJ2ZSByZXByZXNlbnRzIGhvdyB0aGUgZmlsdGVyXG4gICAgICogcmVzcG9uc2VzIHRvIGZyZXF1ZW5jaWVzIGJldHdlZW4gMjBoei0yMGtoei5cbiAgICAgKiBAcGFyYW0gIGxlbiBUaGUgbnVtYmVyIG9mIHZhbHVlcyB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUgYmV0d2VlbiAyMC0yMGtIelxuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbiA9IDEyOCkge1xuICAgICAgICBjb25zdCBmaWx0ZXJDbG9uZSA9IG5ldyBCaXF1YWRGaWx0ZXIoe1xuICAgICAgICAgICAgZnJlcXVlbmN5OiB0aGlzLmZyZXF1ZW5jeS52YWx1ZSxcbiAgICAgICAgICAgIGdhaW46IHRoaXMuZ2Fpbi52YWx1ZSxcbiAgICAgICAgICAgIFE6IHRoaXMuUS52YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMuX3R5cGUsXG4gICAgICAgICAgICBkZXR1bmU6IHRoaXMuZGV0dW5lLnZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhbGwgMXNcbiAgICAgICAgY29uc3QgdG90YWxSZXNwb25zZSA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKS5tYXAoKCkgPT4gMSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGZpbHRlckNsb25lLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbik7XG4gICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKCh2YWwsIGkpID0+IHRvdGFsUmVzcG9uc2VbaV0gKj0gdmFsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZpbHRlckNsb25lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRvdGFsUmVzcG9uc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICAgICAgICBmaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wiZGV0dW5lXCIsIFwiZnJlcXVlbmN5XCIsIFwiZ2FpblwiLCBcIlFcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NjYWxlXCI7XG5pbXBvcnQgeyBQb3cgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1Bvd1wiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEZyZXF1ZW5jeUVudmVsb3BlIGlzIGFuIFtbRW52ZWxvcGVdXSB3aGljaCByYW1wcyBiZXR3ZWVuIFtbYmFzZUZyZXF1ZW5jeV1dXG4gKiBhbmQgW1tvY3RhdmVzXV0uIEl0IGNhbiBhbHNvIGhhdmUgYW4gb3B0aW9uYWwgW1tleHBvbmVudF1dIHRvIGFkanVzdCB0aGUgY3VydmVcbiAqIHdoaWNoIGl0IHJhbXBzLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBjb25zdCBmcmVxRW52ID0gbmV3IFRvbmUuRnJlcXVlbmN5RW52ZWxvcGUoe1xuICogXHRhdHRhY2s6IDAuMixcbiAqIFx0YmFzZUZyZXF1ZW5jeTogXCJDMlwiLFxuICogXHRvY3RhdmVzOiA0XG4gKiB9KTtcbiAqIGZyZXFFbnYuY29ubmVjdChvc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG4gKiBmcmVxRW52LnRyaWdnZXJBdHRhY2soKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeUVudmVsb3BlIGV4dGVuZHMgRW52ZWxvcGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lFbnZlbG9wZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5RW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSB0aGlzLmlucHV0ID0gbmV3IFBvdyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5leHBvbmVudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSB0aGlzLm91dHB1dCA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IHRoaXMuX2Jhc2VGcmVxdWVuY3ksXG4gICAgICAgICAgICBtYXg6IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCB0aGlzLl9vY3RhdmVzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpZy5jaGFpbih0aGlzLl9leHBvbmVudCwgdGhpcy5fc2NhbGUpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVudmVsb3BlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgIGV4cG9uZW50OiAxLFxuICAgICAgICAgICAgb2N0YXZlczogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBlbnZlbG9wZSdzIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIGlzIHRoZSB2YWx1ZSB3aGljaCBpdFxuICAgICAqIHN0YXJ0cyBhdC5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KG1pbikge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeShtaW4pO1xuICAgICAgICBhc3NlcnRSYW5nZShmcmVxLCAwKTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IGZyZXE7XG4gICAgICAgIHRoaXMuX3NjYWxlLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgbWF4IHZhbHVlIHdoZW4gdGhlIG1pbiBjaGFuZ2VzXG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeSB0aGF0IHRoZVxuICAgICAqIGVudmVsb3BlIHdpbGwgc2NhbGUgdG8uXG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3RhdmVzKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuICAgICAgICB0aGlzLl9zY2FsZS5tYXggPSB0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgb2N0YXZlcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBlbnZlbG9wZSdzIGV4cG9uZW50IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBleHBvbmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9uZW50LnZhbHVlO1xuICAgIH1cbiAgICBzZXQgZXhwb25lbnQoZXhwb25lbnQpIHtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQudmFsdWUgPSBleHBvbmVudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3lFbnZlbG9wZS5qcy5tYXAiLCJpbXBvcnQgeyBBbXBsaXR1ZGVFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGVcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4uL2luc3RydW1lbnQvTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgT21uaU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogTW9ub1N5bnRoIGlzIGNvbXBvc2VkIG9mIG9uZSBgb3NjaWxsYXRvcmAsIG9uZSBgZmlsdGVyYCwgYW5kIHR3byBgZW52ZWxvcGVzYC5cbiAqIFRoZSBhbXBsaXR1ZGUgb2YgdGhlIE9zY2lsbGF0b3IgYW5kIHRoZSBjdXRvZmYgZnJlcXVlbmN5IG9mIHRoZVxuICogRmlsdGVyIGFyZSBjb250cm9sbGVkIGJ5IEVudmVsb3Blcy5cbiAqIDxpbWcgc3JjPVwiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZHJhd2luZ3MvZC8xZ2FZMURGOV9IemtvZHFmOEpJMUNnMlZaZndTRWxwRlFmSTk0SVF3YWQzOC9wdWI/dz05MjQmaD0yNDBcIj5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCh7XG4gKiBcdG9zY2lsbGF0b3I6IHtcbiAqIFx0XHR0eXBlOiBcInNxdWFyZVwiXG4gKiBcdH0sXG4gKiBcdGVudmVsb3BlOiB7XG4gKiBcdFx0YXR0YWNrOiAwLjFcbiAqIFx0fVxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm9TeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTW9ub1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gbmV3IE9tbmlPc2NpbGxhdG9yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5vc2NpbGxhdG9yLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5vc2NpbGxhdG9yLmRldHVuZTtcbiAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXIsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZSA9IG5ldyBGcmVxdWVuY3lFbnZlbG9wZShPYmplY3QuYXNzaWduKG9wdGlvbnMuZmlsdGVyRW52ZWxvcGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKG9wdGlvbnMuZW52ZWxvcGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgb3NjaWxsYXRvcnMgdG8gdGhlIG91dHB1dFxuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuY2hhaW4odGhpcy5maWx0ZXIsIHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgZmlsdGVyIGVudmVsb3BlXG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUuY29ubmVjdCh0aGlzLmZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiZmlsdGVyXCIsIFwiZmlsdGVyRW52ZWxvcGVcIiwgXCJlbnZlbG9wZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuOSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZmlsdGVyOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEZpbHRlci5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC42LFxuICAgICAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4yLFxuICAgICAgICAgICAgICAgIGV4cG9uZW50OiAyLFxuICAgICAgICAgICAgICAgIG9jdGF2ZXM6IDMsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMixcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KTtcbiAgICAgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyBjb21wdXRlZEF0dGFjayArIGNvbXB1dGVkRGVjYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9ub1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBNb25vU3ludGggfSBmcm9tIFwiLi9Nb25vU3ludGhcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBHYWluLCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogRHVvU3ludGggaXMgYSBtb25vcGhvbmljIHN5bnRoIGNvbXBvc2VkIG9mIHR3byBbW01vbm9TeW50aHNdXSBydW4gaW4gcGFyYWxsZWwgd2l0aCBjb250cm9sIG92ZXIgdGhlXG4gKiBmcmVxdWVuY3kgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHZvaWNlcyBhbmQgdmlicmF0byBlZmZlY3QuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZHVvU3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGR1b1N5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIyblwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEdW9TeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEdW9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEdW9TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRHVvU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy52b2ljZTAgPSBuZXcgTW9ub1N5bnRoKE9iamVjdC5hc3NpZ24ob3B0aW9ucy52b2ljZTAsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9uc2lsZW5jZTogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcylcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLnZvaWNlMSA9IG5ldyBNb25vU3ludGgoT2JqZWN0LmFzc2lnbihvcHRpb25zLnZvaWNlMSwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdmlicmF0byA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLnZpYnJhdG9SYXRlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAtNTAsXG4gICAgICAgICAgICBtYXg6IDUwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB0aGUgdmlicmF0byBpbW1lZGlhdGVseVxuICAgICAgICB0aGlzLl92aWJyYXRvLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMudmlicmF0b1JhdGUgPSB0aGlzLl92aWJyYXRvLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fdmlicmF0b0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy52aWJyYXRvQW1vdW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpYnJhdG9BbW91bnQgPSB0aGlzLl92aWJyYXRvR2Fpbi5nYWluO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogNDQwXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29udHJvbCB0aGUgdHdvIHZvaWNlcyBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLnZvaWNlMC5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLnZvaWNlMS5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl92aWJyYXRvLmNvbm5lY3QodGhpcy5fdmlicmF0b0dhaW4pO1xuICAgICAgICB0aGlzLl92aWJyYXRvR2Fpbi5mYW4odGhpcy52b2ljZTAuZGV0dW5lLCB0aGlzLnZvaWNlMS5kZXR1bmUpO1xuICAgICAgICB0aGlzLmRldHVuZS5mYW4odGhpcy52b2ljZTAuZGV0dW5lLCB0aGlzLnZvaWNlMS5kZXR1bmUpO1xuICAgICAgICB0aGlzLnZvaWNlMC5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy52b2ljZTEuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInZvaWNlMFwiLCBcInZvaWNlMVwiLCBcImZyZXF1ZW5jeVwiLCBcInZpYnJhdG9BbW91bnRcIiwgXCJ2aWJyYXRvUmF0ZVwiXSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy52b2ljZTAuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgKyB0aGlzLnZvaWNlMS5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmlicmF0b0Ftb3VudDogMC41LFxuICAgICAgICAgICAgdmlicmF0b1JhdGU6IDUsXG4gICAgICAgICAgICBoYXJtb25pY2l0eTogMS41LFxuICAgICAgICAgICAgdm9pY2UwOiBkZWVwTWVyZ2Uob21pdEZyb21PYmplY3QoTW9ub1N5bnRoLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgZmlsdGVyRW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB2b2ljZTE6IGRlZXBNZXJnZShvbWl0RnJvbU9iamVjdChNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UwLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UxLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9pY2UwLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2ljZTEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdmlicmF0by5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudmlicmF0b1JhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92aWJyYXRvR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EdW9TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgTW9kdWxhdGlvblN5bnRoIH0gZnJvbSBcIi4vTW9kdWxhdGlvblN5bnRoXCI7XG4vKipcbiAqIEZNU3ludGggaXMgY29tcG9zZWQgb2YgdHdvIFRvbmUuU3ludGhzIHdoZXJlIG9uZSBUb25lLlN5bnRoIG1vZHVsYXRlc1xuICogdGhlIGZyZXF1ZW5jeSBvZiBhIHNlY29uZCBUb25lLlN5bnRoLiBBIGxvdCBvZiBzcGVjdHJhbCBjb250ZW50XG4gKiBjYW4gYmUgZXhwbG9yZWQgdXNpbmcgdGhlIG1vZHVsYXRpb25JbmRleCBwYXJhbWV0ZXIuIFJlYWQgbW9yZSBhYm91dFxuICogZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzIG9uIFNvdW5kIE9uIFNvdW5kOiBbUGFydCAxXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMjM3MDQvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9hcHIwMC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKSwgW1BhcnQgMl0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDAzMTE1ODM1L2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvbWF5MDAvYXJ0aWNsZXMvc3ludGguaHRtKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZm1TeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzVcIiwgXCI0blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgRk1TeW50aCBleHRlbmRzIE1vZHVsYXRpb25TeW50aCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRk1TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMubW9kdWxhdGlvbkluZGV4LCB0aGlzLl9tb2R1bGF0aW9uTm9kZSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLl9jYXJyaWVyLmRldHVuZSwgdGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb2R1bGF0aW9uU3ludGguZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAxMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GTVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBGTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuLyoqXG4gKiBJbmhhcm1vbmljIHJhdGlvIG9mIGZyZXF1ZW5jaWVzIGJhc2VkIG9uIHRoZSBSb2xhbmQgVFItODA4XG4gKiBUYWtlbiBmcm9tIGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L3BhcGVycy90ci04MDgtY3ltYmFsLXBoeXNpY2FsbHktaW5mb3JtZWQtY2lyY3VpdC1iZW5kYWJsZS1kaWdpdGFsLW1vZGVsXG4gKi9cbmNvbnN0IGluaGFybVJhdGlvcyA9IFsxLjAsIDEuNDgzLCAxLjkzMiwgMi41NDYsIDIuNjMwLCAzLjg5N107XG4vKipcbiAqIEEgaGlnaGx5IGluaGFybW9uaWMgYW5kIHNwZWN0cmFsbHkgY29tcGxleCBzb3VyY2Ugd2l0aCBhIGhpZ2hwYXNzIGZpbHRlclxuICogYW5kIGFtcGxpdHVkZSBlbnZlbG9wZSB3aGljaCBpcyBnb29kIGZvciBtYWtpbmcgbWV0YWxsb3Bob25lIHNvdW5kcy5cbiAqIEJhc2VkIG9uIEN5bWJhbFN5bnRoIGJ5IFtAcG9seXJoeXRobWF0aWNdKGh0dHBzOi8vZ2l0aHViLmNvbS9wb2x5cmh5dGhtYXRpYykuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtTb3VuZCBvbiBTb3VuZF0oaHR0cHM6Ly9zaG9ydHVybC5hdC9yU1oxMikuXG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTWV0YWxTeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRhbFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGFsU3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBGTU9zY2lsbGF0b3JzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZyZXF1ZW5jeSBtdWx0aXBsaWVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRhbFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX2hpZ2hwYXNzID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICAvLyBROiAtMy4wMTAyOTk5NTY2Mzk4MTI1LFxuICAgICAgICAgICAgUTogMCxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluaGFybVJhdGlvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgb3NjID0gbmV3IEZNT3NjaWxsYXRvcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGhhcm1vbmljaXR5OiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgICAgICAgICAgb25zdG9wOiBpID09PSAwID8gKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcykgOiBub09wLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG9zYy5jb25uZWN0KHRoaXMuX2hpZ2hwYXNzKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldID0gb3NjO1xuICAgICAgICAgICAgY29uc3QgbXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBpbmhhcm1SYXRpb3NbaV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVyc1tpXSA9IG11bHQ7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbihtdWx0LCBvc2MuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qob3NjLmRldHVuZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlciA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXg6IDcwMDAsXG4gICAgICAgICAgICBtaW46IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5yZXNvbmFuY2UpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBFbnZlbG9wZSh7XG4gICAgICAgICAgICBhdHRhY2s6IG9wdGlvbnMuZW52ZWxvcGUuYXR0YWNrLFxuICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWNheTogb3B0aW9ucy5lbnZlbG9wZS5kZWNheSxcbiAgICAgICAgICAgIHJlbGVhc2U6IG9wdGlvbnMuZW52ZWxvcGUucmVsZWFzZSxcbiAgICAgICAgICAgIHN1c3RhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmNoYWluKHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIsIHRoaXMuX2hpZ2hwYXNzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGUuZ2Fpbik7XG4gICAgICAgIC8vIHNldCB0aGUgb2N0YXZlc1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBNZXJnZShNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwMSxcbiAgICAgICAgICAgICAgICBkZWNheTogMS40LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDUuMSxcbiAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogMzIsXG4gICAgICAgICAgICBvY3RhdmVzOiAxLjUsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDQwMDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2suXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0aGF0IHRoZSBlbnZlbG9wZSBzaG91bGQgYmUgdHJpZ2dlcmVkIGF0LlxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5zdGFydCh0aW1lKSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IHtcbiAgICAgICAgICAgICAgICBvc2Muc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdGhlIHJlbGVhc2Ugc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtb2R1bGF0aW9uSW5kZXggb2YgdGhlIG9zY2lsbGF0b3JzIHdoaWNoIG1ha2UgdXAgdGhlIHNvdXJjZS5cbiAgICAgKiBzZWUgW1tGTU9zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4XV1cbiAgICAgKiBAbWluIDFcbiAgICAgKiBAbWF4IDEwMFxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uSW5kZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5tb2R1bGF0aW9uSW5kZXgudmFsdWU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uSW5kZXgodmFsKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IChvc2MubW9kdWxhdGlvbkluZGV4LnZhbHVlID0gdmFsKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBoYXJtb25pY2l0eSBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuICAgICAqIHNlZSBUb25lLkZNT3NjaWxsYXRvci5oYXJtb25pY2l0eVxuICAgICAqIEBtaW4gMC4xXG4gICAgICogQG1heCAxMFxuICAgICAqL1xuICAgIGdldCBoYXJtb25pY2l0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLmhhcm1vbmljaXR5LnZhbHVlO1xuICAgIH1cbiAgICBzZXQgaGFybW9uaWNpdHkodmFsKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IChvc2MuaGFybW9uaWNpdHkudmFsdWUgPSB2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvd2VyIGxldmVsIG9mIHRoZSBoaWdocGFzcyBmaWx0ZXIgd2hpY2ggaXMgYXR0YWNoZWQgdG8gdGhlIGVudmVsb3BlLlxuICAgICAqIFRoaXMgdmFsdWUgc2hvdWxkIGJlIGJldHdlZW4gWzAsIDcwMDBdXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA3MDAwXG4gICAgICovXG4gICAgZ2V0IHJlc29uYW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluO1xuICAgIH1cbiAgICBzZXQgcmVzb25hbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiA9IHRoaXMudG9GcmVxdWVuY3kodmFsKTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBcInJlc29uYW5jZVwiIGZyZXF1ZW5jeVxuICAgICAqIHRoYXQgdGhlIGZpbHRlciByYW1wcyBkdXJpbmcgdGhlIGF0dGFjay9kZWNheSBlbnZlbG9wZVxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggOFxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXModmFsKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSB2YWw7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWF4ID0gdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW4gKiBNYXRoLnBvdygyLCB2YWwpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnMuZm9yRWFjaChmcmVxTXVsdCA9PiBmcmVxTXVsdC5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9oaWdocGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGFsU3ludGguanMubWFwIiwiaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyByYW5nZSwgdGltZVJhbmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogTWVtYnJhbmVTeW50aCBtYWtlcyBraWNrIGFuZCB0b20gc291bmRzIHVzaW5nIGEgc2luZ2xlIG9zY2lsbGF0b3JcbiAqIHdpdGggYW4gYW1wbGl0dWRlIGVudmVsb3BlIGFuZCBmcmVxdWVuY3kgcmFtcC4gQSBUb25lLk9tbmlPc2NpbGxhdG9yXG4gKiBpcyByb3V0ZWQgdGhyb3VnaCBhIFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUgdG8gdGhlIG91dHB1dC4gVGhlIGRydW1cbiAqIHF1YWxpdHkgb2YgdGhlIHNvdW5kIGNvbWVzIGZyb20gdGhlIGZyZXF1ZW5jeSBlbnZlbG9wZSBhcHBsaWVkXG4gKiBkdXJpbmcgTWVtYnJhbmVTeW50aC50cmlnZ2VyQXR0YWNrKG5vdGUpLiBUaGUgZnJlcXVlbmN5IGVudmVsb3BlXG4gKiBzdGFydHMgYXQgPGNvZGU+bm90ZSAqIC5vY3RhdmVzPC9jb2RlPiBhbmQgcmFtcHMgdG8gPGNvZGU+bm90ZTwvY29kZT5cbiAqIG92ZXIgdGhlIGR1cmF0aW9uIG9mIDxjb2RlPi5waXRjaERlY2F5PC9jb2RlPi5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1lbWJyYW5lU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMyXCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTWVtYnJhbmVTeW50aCBleHRlbmRzIFN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVtYnJhbmVTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZW1icmFuZVN5bnRoXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQb3J0YW1lbnRvIGlzIGlnbm9yZWQgaW4gdGhpcyBzeW50aC4gdXNlIHBpdGNoIGRlY2F5IGluc3RlYWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVtYnJhbmVTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnBpdGNoRGVjYXkgPSBvcHRpb25zLnBpdGNoRGVjYXk7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwgU3ludGguZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDAxLFxuICAgICAgICAgICAgICAgIGF0dGFja0N1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLjQsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4wMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvY3RhdmVzOiAxMCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwaXRjaERlY2F5OiAwLjA1LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0Tm90ZShub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgaGVydHogPSB0aGlzLnRvRnJlcXVlbmN5KG5vdGUgaW5zdGFuY2VvZiBGcmVxdWVuY3lDbGFzcyA/IG5vdGUudG9GcmVxdWVuY3koKSA6IG5vdGUpO1xuICAgICAgICBjb25zdCBtYXhOb3RlID0gaGVydHogKiB0aGlzLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUobWF4Tm90ZSwgc2Vjb25kcyk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3kuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShoZXJ0eiwgc2Vjb25kcyArIHRoaXMudG9TZWNvbmRzKHRoaXMucGl0Y2hEZWNheSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICByYW5nZSgwKVxuXSwgTWVtYnJhbmVTeW50aC5wcm90b3R5cGUsIFwib2N0YXZlc1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBNZW1icmFuZVN5bnRoLnByb3RvdHlwZSwgXCJwaXRjaERlY2F5XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZW1icmFuZVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuLyoqXG4gKiBUb25lLk5vaXNlU3ludGggaXMgY29tcG9zZWQgb2YgW1tOb2lzZV1dIHRocm91Z2ggYW4gW1tBbXBsaXR1ZGVFbnZlbG9wZV1dLlxuICogYGBgXG4gKiArLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIHwgTm9pc2UgKz4tLT4gQW1wbGl0dWRlRW52ZWxvcGUgKz4tLT4gT3V0cHV0XG4gKiArLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5vaXNlU3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIjhuXCIsIDAuMDUpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE5vaXNlU3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2VTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOb2lzZVN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubm9pc2UgPSBuZXcgTm9pc2UoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0sIG9wdGlvbnMubm9pc2UpKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5lbnZlbG9wZSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBub2lzZSB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMubm9pc2UuY2hhaW4odGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbm9pc2U6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoTm9pc2UuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwid2hpdGVcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZXMuIFVubGlrZSBvdGhlclxuICAgICAqIGluc3RydW1lbnRzLCBUb25lLk5vaXNlU3ludGggZG9lc24ndCBoYXZlIGEgbm90ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vaXNlU3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIG5vaXNlU3ludGgudHJpZ2dlckF0dGFjaygpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gdGhlIGVudmVsb3Blc1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbm9pc2VcbiAgICAgICAgdGhpcy5ub2lzZS5zdGFydCh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5ub2lzZS5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5ub2lzZS5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jU3RhdGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJBdHRhY2tcIiwgMCk7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlclJlbGVhc2VcIiwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm5vaXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5vaXNlU3ludGguanMubWFwIiwiLyoqXG4gKiBBbGwgb2YgdGhlIGNsYXNzZXMgb3IgZnVuY3Rpb25zIHdoaWNoIGFyZSBsb2FkZWQgaW50byB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGVcbiAqL1xuY29uc3Qgd29ya2xldENvbnRleHQgPSBuZXcgU2V0KCk7XG4vKipcbiAqIEFkZCBhIGNsYXNzIHRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkVG9Xb3JrbGV0KGNsYXNzT3JGdW5jdGlvbikge1xuICAgIHdvcmtsZXRDb250ZXh0LmFkZChjbGFzc09yRnVuY3Rpb24pO1xufVxuLyoqXG4gKiBSZWdpc3RlciBhIHByb2Nlc3NvciBpbiB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJQcm9jZXNzb3IobmFtZSwgY2xhc3NEZXNjKSB7XG4gICAgY29uc3QgcHJvY2Vzc29yID0gLyogamF2YXNjcmlwdCAqLyBgcmVnaXN0ZXJQcm9jZXNzb3IoXCIke25hbWV9XCIsICR7Y2xhc3NEZXNjfSlgO1xuICAgIHdvcmtsZXRDb250ZXh0LmFkZChwcm9jZXNzb3IpO1xufVxuLyoqXG4gKiBHZXQgYWxsIG9mIHRoZSBtb2R1bGVzIHdoaWNoIGhhdmUgYmVlbiByZWdpc3RlcmVkIHRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2xldEdsb2JhbFNjb3BlKCkge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHdvcmtsZXRDb250ZXh0KS5qb2luKFwiXFxuXCIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V29ya2xldEdsb2JhbFNjb3BlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBnZXRXb3JrbGV0R2xvYmFsU2NvcGUgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9Xb3JrbGV0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9Xb3JrbGV0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29uc3RydWN0b3Igb3B0aW9ucyBmb3IgdGhlIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMud29ya2xldE9wdGlvbnMgPSB7fTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxiYWNrIHdoaWNoIGlzIGludm9rZWQgd2hlbiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgcHJvY2Vzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbnByb2Nlc3NvcmVycm9yID0gbm9PcDtcbiAgICAgICAgY29uc3QgYmxvYlVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2dldFdvcmtsZXRHbG9iYWxTY29wZSgpXSwgeyB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiIH0pKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IHRoaXMuX2F1ZGlvV29ya2xldE5hbWUoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlHYWluID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgdGhpcy5fZHVtbXlQYXJhbSA9IHRoaXMuX2R1bW15R2Fpbi5nYWluO1xuICAgICAgICAvLyBSZWdpc3RlciB0aGUgcHJvY2Vzc29yXG4gICAgICAgIHRoaXMuY29udGV4dC5hZGRBdWRpb1dvcmtsZXRNb2R1bGUoYmxvYlVybCwgbmFtZSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHdvcmtsZXQgd2hlbiBpdCdzIHJlYWRcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShuYW1lLCB0aGlzLndvcmtsZXRPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLl93b3JrbGV0Lm9ucHJvY2Vzc29yZXJyb3IgPSB0aGlzLm9ucHJvY2Vzc29yZXJyb3IuYmluZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uUmVhZHkodGhpcy5fd29ya2xldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2R1bW15R2Fpbi5kaXNjb25uZWN0KCk7XG4gICAgICAgIGlmICh0aGlzLl93b3JrbGV0KSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0LnBvcnQucG9zdE1lc3NhZ2UoXCJkaXNwb3NlXCIpO1xuICAgICAgICAgICAgdGhpcy5fd29ya2xldC5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvV29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmNvbnN0IHRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIFRoZSBiYXNlIEF1ZGlvV29ya2xldFByb2Nlc3NvciBmb3IgdXNlIGluIFRvbmUuanMuIFdvcmtzIHdpdGggdGhlIFtbVG9uZUF1ZGlvV29ya2xldF1dLiBcblx0ICovXG5cdGNsYXNzIFRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0XG5cdFx0XHRzdXBlcihvcHRpb25zKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogSWYgdGhlIHByb2Nlc3NvciB3YXMgZGlzcG9zZWQgb3Igbm90LiBLZWVwIGFsaXZlIHVudGlsIGl0J3MgZGlzcG9zZWQuXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuZGlzcG9zZWQgPSBmYWxzZTtcblx0XHQgICBcdC8qKiBcblx0XHRcdCAqIFRoZSBudW1iZXIgb2Ygc2FtcGxlcyBpbiB0aGUgcHJvY2Vzc2luZyBibG9ja1xuXHRcdFx0ICovXG5cdFx0XHR0aGlzLmJsb2NrU2l6ZSA9IDEyODtcblx0XHRcdC8qKlxuXHRcdFx0ICogdGhlIHNhbXBsZSByYXRlXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuc2FtcGxlUmF0ZSA9IHNhbXBsZVJhdGU7XG5cblx0XHRcdHRoaXMucG9ydC5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcblx0XHRcdFx0Ly8gd2hlbiBpdCByZWNlaXZlcyBhIGRpc3Bvc2UgXG5cdFx0XHRcdGlmIChldmVudC5kYXRhID09PSBcImRpc3Bvc2VcIikge1xuXHRcdFx0XHRcdHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0fVxuYDtcbmFkZFRvV29ya2xldCh0b25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgXCIuL1RvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IHsgYWRkVG9Xb3JrbGV0IH0gZnJvbSBcIi4vV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY29uc3Qgc2luZ2xlSU9Qcm9jZXNzID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBBYnN0cmFjdCBjbGFzcyBmb3IgYSBzaW5nbGUgaW5wdXQvb3V0cHV0IHByb2Nlc3Nvci4gXG5cdCAqIGhhcyBhICdnZW5lcmF0ZScgZnVuY3Rpb24gd2hpY2ggcHJvY2Vzc2VzIG9uZSBzYW1wbGUgYXQgYSB0aW1lXG5cdCAqL1xuXHRjbGFzcyBTaW5nbGVJT1Byb2Nlc3NvciBleHRlbmRzIFRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0c3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7XG5cdFx0XHRcdG51bWJlck9mSW5wdXRzOiAxLFxuXHRcdFx0XHRudW1iZXJPZk91dHB1dHM6IDFcblx0XHRcdH0pKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogSG9sZHMgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciBhbmQgYSBzaW5nbGUgdmFsdWUgb2YgdGhhdFxuXHRcdFx0ICogcGFyYW1ldGVyIGF0IHRoZSBjdXJyZW50IHNhbXBsZVxuXHRcdFx0ICogQHR5cGUgeyBbbmFtZTogc3RyaW5nXTogbnVtYmVyIH1cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5wYXJhbXMgPSB7fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIEdlbmVyYXRlIGFuIG91dHB1dCBzYW1wbGUgZnJvbSB0aGUgaW5wdXQgc2FtcGxlIGFuZCBwYXJhbWV0ZXJzXG5cdFx0ICogQGFic3RyYWN0XG5cdFx0ICogQHBhcmFtIGlucHV0IG51bWJlclxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSBwYXJhbWV0ZXJzIHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9XG5cdFx0ICogQHJldHVybnMgbnVtYmVyXG5cdFx0ICovXG5cdFx0Z2VuZXJhdGUoKXt9XG5cblx0XHQvKipcblx0XHQgKiBVcGRhdGUgdGhlIHByaXZhdGUgcGFyYW1zIG9iamVjdCB3aXRoIHRoZSBcblx0XHQgKiB2YWx1ZXMgb2YgdGhlIHBhcmFtZXRlcnMgYXQgdGhlIGdpdmVuIGluZGV4XG5cdFx0ICogQHBhcmFtIHBhcmFtZXRlcnMgeyBbbmFtZTogc3RyaW5nXTogRmxvYXQzMkFycmF5IH0sXG5cdFx0ICogQHBhcmFtIGluZGV4IG51bWJlclxuXHRcdCAqL1xuXHRcdHVwZGF0ZVBhcmFtcyhwYXJhbWV0ZXJzLCBpbmRleCkge1xuXHRcdFx0Zm9yIChjb25zdCBwYXJhbU5hbWUgaW4gcGFyYW1ldGVycykge1xuXHRcdFx0XHRjb25zdCBwYXJhbSA9IHBhcmFtZXRlcnNbcGFyYW1OYW1lXTtcblx0XHRcdFx0aWYgKHBhcmFtLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0XHR0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdW2luZGV4XTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdWzBdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogUHJvY2VzcyBhIHNpbmdsZSBmcmFtZSBvZiB0aGUgYXVkaW9cblx0XHQgKiBAcGFyYW0gaW5wdXRzIEZsb2F0MzJBcnJheVtdW11cblx0XHQgKiBAcGFyYW0gb3V0cHV0cyBGbG9hdDMyQXJyYXlbXVtdXG5cdFx0ICovXG5cdFx0cHJvY2VzcyhpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdO1xuXHRcdFx0Y29uc3Qgb3V0cHV0ID0gb3V0cHV0c1swXTtcblx0XHRcdC8vIGdldCB0aGUgcGFyYW1ldGVyIHZhbHVlc1xuXHRcdFx0Y29uc3QgY2hhbm5lbENvdW50ID0gTWF0aC5tYXgoaW5wdXQgJiYgaW5wdXQubGVuZ3RoIHx8IDAsIG91dHB1dC5sZW5ndGgpO1xuXHRcdFx0Zm9yIChsZXQgc2FtcGxlID0gMDsgc2FtcGxlIDwgdGhpcy5ibG9ja1NpemU7IHNhbXBsZSsrKSB7XG5cdFx0XHRcdHRoaXMudXBkYXRlUGFyYW1zKHBhcmFtZXRlcnMsIHNhbXBsZSk7XG5cdFx0XHRcdGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgY2hhbm5lbENvdW50OyBjaGFubmVsKyspIHtcblx0XHRcdFx0XHRjb25zdCBpbnB1dFNhbXBsZSA9IGlucHV0ICYmIGlucHV0Lmxlbmd0aCA/IGlucHV0W2NoYW5uZWxdW3NhbXBsZV0gOiAwO1xuXHRcdFx0XHRcdG91dHB1dFtjaGFubmVsXVtzYW1wbGVdID0gdGhpcy5nZW5lcmF0ZShpbnB1dFNhbXBsZSwgY2hhbm5lbCwgdGhpcy5wYXJhbXMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gIXRoaXMuZGlzcG9zZWQ7XG5cdFx0fVxuXHR9O1xuYDtcbmFkZFRvV29ya2xldChzaW5nbGVJT1Byb2Nlc3MpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmNvbnN0IGRlbGF5TGluZSA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogQSBtdWx0aWNoYW5uZWwgYnVmZmVyIGZvciB1c2Ugd2l0aGluIGFuIEF1ZGlvV29ya2xldFByb2Nlc3NvciBhcyBhIGRlbGF5IGxpbmVcblx0ICovXG5cdGNsYXNzIERlbGF5TGluZSB7XG5cdFx0XG5cdFx0Y29uc3RydWN0b3Ioc2l6ZSwgY2hhbm5lbHMpIHtcblx0XHRcdHRoaXMuYnVmZmVyID0gW107XG5cdFx0XHR0aGlzLndyaXRlSGVhZCA9IFtdXG5cdFx0XHR0aGlzLnNpemUgPSBzaXplO1xuXG5cdFx0XHQvLyBjcmVhdGUgdGhlIGVtcHR5IGNoYW5uZWxzXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHtcblx0XHRcdFx0dGhpcy5idWZmZXJbaV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuc2l6ZSk7XG5cdFx0XHRcdHRoaXMud3JpdGVIZWFkW2ldID0gMDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBQdXNoIGEgdmFsdWUgb250byB0aGUgZW5kXG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIHZhbHVlIG51bWJlclxuXHRcdCAqL1xuXHRcdHB1c2goY2hhbm5lbCwgdmFsdWUpIHtcblx0XHRcdHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdICs9IDE7XG5cdFx0XHRpZiAodGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gPiB0aGlzLnNpemUpIHtcblx0XHRcdFx0dGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gPSAwO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5idWZmZXJbY2hhbm5lbF1bdGhpcy53cml0ZUhlYWRbY2hhbm5lbF1dID0gdmFsdWU7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogR2V0IHRoZSByZWNvcmRlZCB2YWx1ZSBvZiB0aGUgY2hhbm5lbCBnaXZlbiB0aGUgZGVsYXlcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gZGVsYXkgbnVtYmVyIGRlbGF5IHNhbXBsZXNcblx0XHQgKi9cblx0XHRnZXQoY2hhbm5lbCwgZGVsYXkpIHtcblx0XHRcdGxldCByZWFkSGVhZCA9IHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdIC0gTWF0aC5mbG9vcihkZWxheSk7XG5cdFx0XHRpZiAocmVhZEhlYWQgPCAwKSB7XG5cdFx0XHRcdHJlYWRIZWFkICs9IHRoaXMuc2l6ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzLmJ1ZmZlcltjaGFubmVsXVtyZWFkSGVhZF07XG5cdFx0fVxuXHR9XG5gO1xuYWRkVG9Xb3JrbGV0KGRlbGF5TGluZSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWxheUxpbmUud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgXCIuLi8uLi9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IFwiLi4vLi4vY29yZS93b3JrbGV0L0RlbGF5TGluZS53b3JrbGV0XCI7XG5pbXBvcnQgeyByZWdpc3RlclByb2Nlc3NvciB9IGZyb20gXCIuLi8uLi9jb3JlL3dvcmtsZXQvV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY29uc3Qgd29ya2xldE5hbWUgPSBcImZlZWRiYWNrLWNvbWItZmlsdGVyXCI7XG5jb25zdCBmZWVkYmFja0NvbWJGaWx0ZXIgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0Y2xhc3MgRmVlZGJhY2tDb21iRmlsdGVyV29ya2xldCBleHRlbmRzIFNpbmdsZUlPUHJvY2Vzc29yIHtcblxuXHRcdGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcblx0XHRcdHN1cGVyKG9wdGlvbnMpO1xuXHRcdFx0dGhpcy5kZWxheUxpbmUgPSBuZXcgRGVsYXlMaW5lKHRoaXMuc2FtcGxlUmF0ZSwgb3B0aW9ucy5jaGFubmVsQ291bnQgfHwgMik7XG5cdFx0fVxuXG5cdFx0c3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHtcblx0XHRcdHJldHVybiBbe1xuXHRcdFx0XHRuYW1lOiBcImRlbGF5VGltZVwiLFxuXHRcdFx0XHRkZWZhdWx0VmFsdWU6IDAuMSxcblx0XHRcdFx0bWluVmFsdWU6IDAsXG5cdFx0XHRcdG1heFZhbHVlOiAxLFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogXCJrLXJhdGVcIlxuXHRcdFx0fSwge1xuXHRcdFx0XHRuYW1lOiBcImZlZWRiYWNrXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMC41LFxuXHRcdFx0XHRtaW5WYWx1ZTogMCxcblx0XHRcdFx0bWF4VmFsdWU6IDAuOTk5OSxcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6IFwiay1yYXRlXCJcblx0XHRcdH1dO1xuXHRcdH1cblxuXHRcdGdlbmVyYXRlKGlucHV0LCBjaGFubmVsLCBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRjb25zdCBkZWxheWVkU2FtcGxlID0gdGhpcy5kZWxheUxpbmUuZ2V0KGNoYW5uZWwsIHBhcmFtZXRlcnMuZGVsYXlUaW1lICogdGhpcy5zYW1wbGVSYXRlKTtcblx0XHRcdHRoaXMuZGVsYXlMaW5lLnB1c2goY2hhbm5lbCwgaW5wdXQgKyBkZWxheWVkU2FtcGxlICogcGFyYW1ldGVycy5mZWVkYmFjayk7XG5cdFx0XHRyZXR1cm4gZGVsYXllZFNhbXBsZTtcblx0XHR9XG5cdH1cbmA7XG5yZWdpc3RlclByb2Nlc3Nvcih3b3JrbGV0TmFtZSwgZmVlZGJhY2tDb21iRmlsdGVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZlZWRiYWNrQ29tYkZpbHRlci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Xb3JrbGV0IH0gZnJvbSBcIi4uLy4uL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0XCI7XG5pbXBvcnQgeyB3b3JrbGV0TmFtZSB9IGZyb20gXCIuL0ZlZWRiYWNrQ29tYkZpbHRlci53b3JrbGV0XCI7XG4vKipcbiAqIENvbWIgZmlsdGVycyBhcmUgYmFzaWMgYnVpbGRpbmcgYmxvY2tzIGZvciBwaHlzaWNhbCBtb2RlbGluZy4gUmVhZCBtb3JlXG4gKiBhYm91dCBjb21iIGZpbHRlcnMgb24gW0NDUk1BJ3Mgd2Vic2l0ZV0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL0ZlZWRiYWNrX0NvbWJfRmlsdGVycy5odG1sKS5cbiAqXG4gKiBUaGlzIGNvbWIgZmlsdGVyIGlzIGltcGxlbWVudGVkIHdpdGggdGhlIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggYWxsb3dzIGl0IHRvIGhhdmUgZmVlZGJhY2sgZGVsYXlzIGxlc3MgdGhhbiB0aGVcbiAqIFdlYiBBdWRpbyBwcm9jZXNzaW5nIGJsb2NrIG9mIDEyOCBzYW1wbGVzLiBUaGVyZSBpcyBhIHBvbHlmaWxsIGZvciBicm93c2VycyB0aGF0IGRvbid0IHlldCBzdXBwb3J0IHRoZVxuICogQXVkaW9Xb3JrbGV0Tm9kZSwgYnV0IGl0IHdpbGwgYWRkIHNvbWUgbGF0ZW5jeSBhbmQgaGF2ZSBzbG93ZXIgcGVyZm9ybWFuY2UgdGhhbiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZlZWRiYWNrQ29tYkZpbHRlciBleHRlbmRzIFRvbmVBdWRpb1dvcmtsZXQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0NvbWJGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kdW1teVBhcmFtLFxuICAgICAgICAgICAgc3dhcHBhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kdW1teVBhcmFtLFxuICAgICAgICAgICAgc3dhcHBhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicmVzb25hbmNlXCIsIFwiZGVsYXlUaW1lXCJdKTtcbiAgICB9XG4gICAgX2F1ZGlvV29ya2xldE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB3b3JrbGV0TmFtZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgb25SZWFkeShub2RlKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgbm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25zdCBkZWxheVRpbWUgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiZGVsYXlUaW1lXCIpO1xuICAgICAgICA7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLnNldFBhcmFtKGRlbGF5VGltZSk7XG4gICAgICAgIGNvbnN0IGZlZWRiYWNrID0gbm9kZS5wYXJhbWV0ZXJzLmdldChcImZlZWRiYWNrXCIpO1xuICAgICAgICA7XG4gICAgICAgIHRoaXMucmVzb25hbmNlLnNldFBhcmFtKGZlZWRiYWNrKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVzb25hbmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tDb21iRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBBIG9uZSBwb2xlIGZpbHRlciB3aXRoIDZkYi1wZXItb2N0YXZlIHJvbGxvZmYuIEVpdGhlciBcImhpZ2hwYXNzXCIgb3IgXCJsb3dwYXNzXCIuXG4gKiBOb3RlIHRoYXQgY2hhbmdpbmcgdGhlIHR5cGUgb3IgZnJlcXVlbmN5IG1heSByZXN1bHQgaW4gYSBkaXNjb250aW51aXR5IHdoaWNoXG4gKiBjYW4gc291bmQgbGlrZSBhIGNsaWNrIG9yIHBvcC5cbiAqIFJlZmVyZW5jZXM6XG4gKiAqIGh0dHA6Ly93d3cuZWFybGV2ZWwuY29tL21haW4vMjAxMi8xMi8xNS9hLW9uZS1wb2xlLWZpbHRlci9cbiAqICogaHR0cDovL3d3dy5kc3BndWlkZS5jb20vY2gxOS8yLmh0bVxuICogKiBodHRwczovL2dpdGh1Yi5jb20vdml0YWxpeS1ib2Jyb3YvanMtcm9ja3MvYmxvYi9tYXN0ZXIvc3JjL2FwcC9hdWRpby9lZmZlY3RzL29uZS1wb2xlLWZpbHRlcnMudHNcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE9uZVBvbGVGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT25lUG9sZUZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPbmVQb2xlRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhPbmVQb2xlRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IG9wdGlvbnMuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUZpbHRlcigpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiA4ODAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgZmlsdGVyIGFuZCBkaXNwb3NlIHRoZSBvbGQgb25lXG4gICAgICovXG4gICAgX2NyZWF0ZUZpbHRlcigpIHtcbiAgICAgICAgY29uc3Qgb2xkRmlsdGVyID0gdGhpcy5fZmlsdGVyO1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSh0aGlzLl9mcmVxdWVuY3kpO1xuICAgICAgICBjb25zdCB0ID0gMSAvICgyICogTWF0aC5QSSAqIGZyZXEpO1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJsb3dwYXNzXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGEwID0gMSAvICh0ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3QgYjEgPSBhMCAtIDE7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFthMCwgMF0sIFsxLCBiMV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYjEgPSAxIC8gKHQgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSkgLSAxO1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihbMSwgLTFdLCBbMSwgYjFdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2ZpbHRlciwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBpZiAob2xkRmlsdGVyKSB7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIGl0IG9uIHRoZSBuZXh0IGJsb2NrXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdChvbGRGaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICBvbGRGaWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHRoaXMuYmxvY2tUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBmcmVxdWVuY3koZnEpIHtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gZnE7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUZpbHRlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgT25lUG9sZSBGaWx0ZXIgdHlwZSwgZWl0aGVyIFwiaGlnaHBhc3NcIiBvciBcImxvd3Bhc3NcIlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodCkge1xuICAgICAgICB0aGlzLl90eXBlID0gdDtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIGNvbnN0IGZyZXFWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm0gPSBNYXRoLnBvdyhpIC8gbGVuLCAyKTtcbiAgICAgICAgICAgIGNvbnN0IGZyZXEgPSBub3JtICogKDIwMDAwIC0gMjApICsgMjA7XG4gICAgICAgICAgICBmcmVxVmFsdWVzW2ldID0gZnJlcTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYWdWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGNvbnN0IHBoYXNlVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcVZhbHVlcywgbWFnVmFsdWVzLCBwaGFzZVZhbHVlcyk7XG4gICAgICAgIHJldHVybiBtYWdWYWx1ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T25lUG9sZUZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEZlZWRiYWNrQ29tYkZpbHRlciB9IGZyb20gXCIuL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgT25lUG9sZUZpbHRlciB9IGZyb20gXCIuL09uZVBvbGVGaWx0ZXJcIjtcbi8qKlxuICogQSBsb3dwYXNzIGZlZWRiYWNrIGNvbWIgZmlsdGVyLiBJdCBpcyBzaW1pbGFyIHRvXG4gKiBbW0ZlZWRiYWNrQ29tYkZpbHRlcl1dLCBidXQgaW5jbHVkZXMgYSBsb3dwYXNzIGZpbHRlci5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIExvd3Bhc3NDb21iRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExvd3Bhc3NDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCIsIFwiZGFtcGVuaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTG93cGFzc0NvbWJGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExvd3Bhc3NDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCIsIFwiZGFtcGVuaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlciA9IHRoaXMub3V0cHV0ID0gbmV3IEZlZWRiYWNrQ29tYkZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWxheVRpbWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgcmVzb25hbmNlOiBvcHRpb25zLnJlc29uYW5jZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fY29tYkZpbHRlci5kZWxheVRpbWU7XG4gICAgICAgIHRoaXMucmVzb25hbmNlID0gdGhpcy5fY29tYkZpbHRlci5yZXNvbmFuY2U7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MgPSB0aGlzLmlucHV0ID0gbmV3IE9uZVBvbGVGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmRhbXBlbmluZyxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fbG93cGFzcy5jb25uZWN0KHRoaXMuX2NvbWJGaWx0ZXIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGFtcGVuaW5nOiAzMDAwLFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjEsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkYW1wZW5pbmcgY29udHJvbCBvZiB0aGUgZmVlZGJhY2tcbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG93cGFzcy5mcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBkYW1wZW5pbmcoZnEpIHtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5mcmVxdWVuY3kgPSBmcTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvd3Bhc3NDb21iRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IExvd3Bhc3NDb21iRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuLyoqXG4gKiBLYXJwbHVzLVN0cmluZyBzdHJpbmcgc3ludGhlc2lzLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBsdWNreSA9IG5ldyBUb25lLlBsdWNrU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkM0XCIsIFwiKzAuNVwiKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzNcIiwgXCIrMVwiKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzJcIiwgXCIrMS41XCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDMVwiLCBcIisyXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBsdWNrU3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGx1Y2tTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQbHVja1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQbHVja1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX25vaXNlID0gbmV3IE5vaXNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwicGlua1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFja05vaXNlID0gb3B0aW9ucy5hdHRhY2tOb2lzZTtcbiAgICAgICAgdGhpcy5fbGZjZiA9IG5ldyBMb3dwYXNzQ29tYkZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgcmVzb25hbmNlOiBvcHRpb25zLnJlc29uYW5jZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzb25hbmNlID0gb3B0aW9ucy5yZXNvbmFuY2U7XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcbiAgICAgICAgdGhpcy5fbm9pc2UuY29ubmVjdCh0aGlzLl9sZmNmKTtcbiAgICAgICAgdGhpcy5fbGZjZi5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrTm9pc2U6IDEsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IDQwMDAsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDAuNyxcbiAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGFtcGVuaW5nIGNvbnRyb2wuIGkuZS4gdGhlIGxvd3Bhc3MgZmlsdGVyIGZyZXF1ZW5jeSBvZiB0aGUgY29tYiBmaWx0ZXJcbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDcwMDBcbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZjZi5kYW1wZW5pbmc7XG4gICAgfVxuICAgIHNldCBkYW1wZW5pbmcoZnEpIHtcbiAgICAgICAgdGhpcy5fbGZjZi5kYW1wZW5pbmcgPSBmcTtcbiAgICB9XG4gICAgdHJpZ2dlckF0dGFjayhub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KG5vdGUpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGRlbGF5QW1vdW50ID0gMSAvIGZyZXE7XG4gICAgICAgIHRoaXMuX2xmY2YuZGVsYXlUaW1lLnNldFZhbHVlQXRUaW1lKGRlbGF5QW1vdW50LCB0aW1lKTtcbiAgICAgICAgdGhpcy5fbm9pc2Uuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX25vaXNlLnN0b3AodGltZSArIGRlbGF5QW1vdW50ICogdGhpcy5hdHRhY2tOb2lzZSk7XG4gICAgICAgIHRoaXMuX2xmY2YucmVzb25hbmNlLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2Uuc2V0VmFsdWVBdFRpbWUodGhpcy5yZXNvbmFuY2UsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmFtcCBkb3duIHRoZSBbW3Jlc29uYW5jZV1dIHRvIDAgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIHJlbGVhc2UgdGltZS5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmY2YucmVzb25hbmNlLmxpbmVhclJhbXBUbygwLCB0aGlzLnJlbGVhc2UsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ub2lzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmY2YuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbHVja1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IE1pZGlDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvTWlkaVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgU3ludGggfSBmcm9tIFwiLi9TeW50aFwiO1xuaW1wb3J0IHsgYXNzZXJ0LCB3YXJuIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQb2x5U3ludGggaGFuZGxlcyB2b2ljZSBjcmVhdGlvbiBhbmQgYWxsb2NhdGlvbiBmb3IgYW55XG4gKiBpbnN0cnVtZW50cyBwYXNzZWQgaW4gYXMgdGhlIHNlY29uZCBwYXJhbXRlci4gUG9seVN5bnRoIGlzXG4gKiBub3QgYSBzeW50aGVzaXplciBieSBpdHNlbGYsIGl0IG1lcmVseSBtYW5hZ2VzIHZvaWNlcyBvZlxuICogb25lIG9mIHRoZSBvdGhlciB0eXBlcyBvZiBzeW50aHMsIGFsbG93aW5nIGFueSBvZiB0aGVcbiAqIG1vbm9waG9uaWMgc3ludGhlc2l6ZXJzIHRvIGJlIHBvbHlwaG9uaWMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gc2V0IHRoZSBhdHRyaWJ1dGVzIGFjcm9zcyBhbGwgdGhlIHZvaWNlcyB1c2luZyAnc2V0J1xuICogc3ludGguc2V0KHsgZGV0dW5lOiAtMTIwMCB9KTtcbiAqIC8vIHBsYXkgYSBjaG9yZFxuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzRcIiwgXCJFNFwiLCBcIkE0XCJdLCAxKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQb2x5U3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUG9seVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9pY2VcIiwgXCJvcHRpb25zXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUG9seVN5bnRoXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdm9pY2VzIHdoaWNoIGFyZSBub3QgY3VycmVudGx5IGluIHVzZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYXZhaWxhYmxlVm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3VycmVudGx5IGFjdGl2ZSB2b2ljZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBhbGxvY2F0ZWQgdm9pY2VzIGZvciB0aGlzIHN5bnRoLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgR0MgdGltZW91dC4gSGVsZCBzbyB0aGF0IGl0IGNvdWxkIGJlIGNhbmNlbGxlZCB3aGVuIHRoZSBub2RlIGlzIGRpc3Bvc2VkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2NUaW1lb3V0ID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIG1vdmluZyBhdmVyYWdlIG9mIHRoZSBudW1iZXIgb2YgYWN0aXZlIHZvaWNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQb2x5U3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2ljZVwiLCBcIm9wdGlvbnNcIl0pO1xuICAgICAgICAvLyBjaGVjayBhZ2FpbnN0IHRoZSBvbGQgQVBJIChwcmUgMTQuMy4wKVxuICAgICAgICBhc3NlcnQoIWlzTnVtYmVyKG9wdGlvbnMudm9pY2UpLCBcIkRFUFJFQ0FURUQ6IFRoZSBwb2x5cGhvbnkgY291bnQgaXMgbm8gbG9uZ2VyIHRoZSBmaXJzdCBhcmd1bWVudC5cIik7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gb3B0aW9ucy52b2ljZS5nZXREZWZhdWx0cygpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRzLCBvcHRpb25zLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLnZvaWNlID0gb3B0aW9ucy52b2ljZTtcbiAgICAgICAgdGhpcy5tYXhQb2x5cGhvbnkgPSBvcHRpb25zLm1heFBvbHlwaG9ueTtcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBmaXJzdCB2b2ljZVxuICAgICAgICB0aGlzLl9kdW1teVZvaWNlID0gdGhpcy5fZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCk7XG4gICAgICAgIC8vIHJlbW92ZSBpdCBmcm9tIHRoZSB2b2ljZXMgbGlzdFxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3ZvaWNlcy5pbmRleE9mKHRoaXMuX2R1bW15Vm9pY2UpO1xuICAgICAgICB0aGlzLl92b2ljZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgLy8ga2ljayBvZmYgdGhlIEdDIGludGVydmFsXG4gICAgICAgIHRoaXMuX2djVGltZW91dCA9IHRoaXMuY29udGV4dC5zZXRJbnRlcnZhbCh0aGlzLl9jb2xsZWN0R2FyYmFnZS5iaW5kKHRoaXMpLCAxKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1heFBvbHlwaG9ueTogMzIsXG4gICAgICAgICAgICBvcHRpb25zOiB7fSxcbiAgICAgICAgICAgIHZvaWNlOiBTeW50aCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgYWN0aXZlIHZvaWNlcy5cbiAgICAgKi9cbiAgICBnZXQgYWN0aXZlVm9pY2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlVm9pY2VzLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCB3aGVuIHRoZSBzb3VyY2UgaXMgZG9uZSBtYWtpbmcgc291bmQsIHNvIHRoYXQgaXQgY2FuIGJlXG4gICAgICogcmVhZGRlZCB0byB0aGUgcG9vbCBvZiBhdmFpbGFibGUgdm9pY2VzXG4gICAgICovXG4gICAgX21ha2VWb2ljZUF2YWlsYWJsZSh2b2ljZSkge1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMucHVzaCh2b2ljZSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgbWlkaSBub3RlIGZyb20gJ2FjdGl2ZSB2b2ljZXMnXG4gICAgICAgIGNvbnN0IGFjdGl2ZVZvaWNlSW5kZXggPSB0aGlzLl9hY3RpdmVWb2ljZXMuZmluZEluZGV4KChlKSA9PiBlLnZvaWNlID09PSB2b2ljZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5zcGxpY2UoYWN0aXZlVm9pY2VJbmRleCwgMSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbiBhdmFpbGFibGUgdm9pY2UgZnJvbSB0aGUgcG9vbCBvZiBhdmFpbGFibGUgdm9pY2VzLlxuICAgICAqIElmIG9uZSBpcyBub3QgYXZhaWxhYmxlIGFuZCB0aGUgbWF4UG9seXBob255IGxpbWl0IGlzIHJlYWNoZWQsXG4gICAgICogc3RlYWwgYSB2b2ljZSwgb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuICAgICAqL1xuICAgIF9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKSB7XG4gICAgICAgIC8vIGlmIHRoZXJlIGFyZSBhdmFpbGFibGUgdm9pY2VzLCByZXR1cm4gdGhlIGZpcnN0IG9uZVxuICAgICAgICBpZiAodGhpcy5fYXZhaWxhYmxlVm9pY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5zaGlmdCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3ZvaWNlcy5sZW5ndGggPCB0aGlzLm1heFBvbHlwaG9ueSkge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIHRoZXJlIGlzIHN0aWxsIG1vcmUgbWF4UG9seXBob255LCBtYWtlIGEgbmV3IHZvaWNlXG4gICAgICAgICAgICBjb25zdCB2b2ljZSA9IG5ldyB0aGlzLnZvaWNlKE9iamVjdC5hc3NpZ24odGhpcy5vcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIG9uc2lsZW5jZTogdGhpcy5fbWFrZVZvaWNlQXZhaWxhYmxlLmJpbmQodGhpcyksXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB2b2ljZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX3ZvaWNlcy5wdXNoKHZvaWNlKTtcbiAgICAgICAgICAgIHJldHVybiB2b2ljZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdhcm4oXCJNYXggcG9seXBob255IGV4Y2VlZGVkLiBOb3RlIGRyb3BwZWQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9jY2FzaW9uYWxseSBjaGVjayBpZiB0aGVyZSBhcmUgYW55IGFsbG9jYXRlZCB2b2ljZXMgd2hpY2ggY2FuIGJlIGNsZWFuZWQgdXAuXG4gICAgICovXG4gICAgX2NvbGxlY3RHYXJiYWdlKCkge1xuICAgICAgICB0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzID0gTWF0aC5tYXgodGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyAqIDAuOTUsIHRoaXMuYWN0aXZlVm9pY2VzKTtcbiAgICAgICAgaWYgKHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5sZW5ndGggJiYgdGhpcy5fdm9pY2VzLmxlbmd0aCA+IE1hdGguY2VpbCh0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzICsgMSkpIHtcbiAgICAgICAgICAgIC8vIHRha2Ugb2ZmIGFuIGF2YWlsYWJsZSBub3RlXG4gICAgICAgICAgICBjb25zdCBmaXJzdEF2YWlsID0gdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnNoaWZ0KCk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3ZvaWNlcy5pbmRleE9mKGZpcnN0QXZhaWwpO1xuICAgICAgICAgICAgdGhpcy5fdm9pY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGV4dC5pc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBmaXJzdEF2YWlsLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2Qgd2hpY2ggdHJpZ2dlcnMgdGhlIGF0dGFja1xuICAgICAqL1xuICAgIF90cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaU5vdGUgPSBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICBjb25zdCB2b2ljZSA9IHRoaXMuX2dldE5leHRBdmFpbGFibGVWb2ljZSgpO1xuICAgICAgICAgICAgaWYgKHZvaWNlKSB7XG4gICAgICAgICAgICAgICAgdm9pY2UudHJpZ2dlckF0dGFjayhub3RlLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBtaWRpOiBtaWRpTm90ZSwgdm9pY2UsIHJlbGVhc2VkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2Qgd2hpY2ggdHJpZ2dlcnMgdGhlIHJlbGVhc2VcbiAgICAgKi9cbiAgICBfdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgbm90ZXMuZm9yRWFjaChub3RlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGlOb3RlID0gbmV3IE1pZGlDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9hY3RpdmVWb2ljZXMuZmluZCgoeyBtaWRpLCByZWxlYXNlZCB9KSA9PiBtaWRpID09PSBtaWRpTm90ZSAmJiAhcmVsZWFzZWQpO1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gdHJpZ2dlciByZWxlYXNlIG9uIHRoYXQgbm90ZVxuICAgICAgICAgICAgICAgIGV2ZW50LnZvaWNlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICAgICAgICAgIC8vIG1hcmsgaXQgYXMgcmVsZWFzZWRcbiAgICAgICAgICAgICAgICBldmVudC5yZWxlYXNlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCBub3RlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIHRoZSBhdHRhY2svcmVsZWFzZSBldmVudHMuIElmIHRoZSB0aW1lIGlzIGluIHRoZSBmdXR1cmUsIHRoZW4gaXQgc2hvdWxkIHNldCBhIHRpbWVvdXRcbiAgICAgKiB0byB3YWl0IGZvciBqdXN0LWluLXRpbWUgc2NoZWR1bGluZ1xuICAgICAqL1xuICAgIF9zY2hlZHVsZUV2ZW50KHR5cGUsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuZGlzcG9zZWQsIFwiU3ludGggd2FzIGFscmVhZHkgZGlzcG9zZWRcIik7XG4gICAgICAgIC8vIGlmIHRoZSBub3RlcyBhcmUgZ3JlYXRlciB0aGFuIHRoaXMgYW1vdW50IG9mIHRpbWUgaW4gdGhlIGZ1dHVyZSwgdGhleSBzaG91bGQgYmUgc2NoZWR1bGVkIHdpdGggc2V0VGltZW91dFxuICAgICAgICBpZiAodGltZSA8PSB0aGlzLm5vdygpKSB7XG4gICAgICAgICAgICAvLyBkbyBpdCBpbW1lZGlhdGVseVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09IFwiYXR0YWNrXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzY2hlZHVsZSBpdCB0byBzdGFydCBpbiB0aGUgZnV0dXJlXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVFdmVudCh0eXBlLCBub3RlcywgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgfSwgdGltZSAtIHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgc3RhcnQgdGltZSBvZiB0aGUgbm90ZS5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5GTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gdHJpZ2dlciBhIGNob3JkIGltbWVkaWF0ZWx5IHdpdGggYSB2ZWxvY2l0eSBvZiAwLjJcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFtcIkFiM1wiLCBcIkM0XCIsIFwiRjVcIl0sIFRvbmUubm93KCksIDAuMik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayhub3RlcywgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KFwiYXR0YWNrXCIsIG5vdGVzLCBjb21wdXRlZFRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIG5vdGUuIFVubGlrZSBtb25vcGhvbmljIGluc3RydW1lbnRzLFxuICAgICAqIGEgbm90ZSAob3IgYXJyYXkgb2Ygbm90ZXMpIG5lZWRzIHRvIGJlIHBhc3NlZCBpbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSByZWxlYXNlIHdpbGwgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuQU1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBvbHkudHJpZ2dlckF0dGFjayhbXCJBYjNcIiwgXCJDNFwiLCBcIkY1XCJdKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIG9mIHRoZSBnaXZlbiBub3Rlcy5cbiAgICAgKiBwb2x5LnRyaWdnZXJSZWxlYXNlKFtcIkFiM1wiLCBcIkM0XCJdLCBcIisxXCIpO1xuICAgICAqIHBvbHkudHJpZ2dlclJlbGVhc2UoXCJGNVwiLCBcIiszXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVFdmVudChcInJlbGVhc2VcIiwgbm90ZXMsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHJlbGVhc2UgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkdXJhdGlvblxuICAgICAqIEBwYXJhbSAgbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGUgIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIHRoZSBkdXJhdGlvbiBvZiB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgdGltZSAgaWYgbm8gdGltZSBpcyBnaXZlbiwgZGVmYXVsdHMgdG8gbm93XG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSB0aGUgdmVsb2NpdHkgb2YgdGhlIGF0dGFjayAoMC0xKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcG9seSA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkFNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBjYW4gcGFzcyBpbiBhbiBhcnJheSBvZiBkdXJhdGlvbnMgYXMgd2VsbFxuICAgICAqIHBvbHkudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiRWIzXCIsIFwiRzRcIiwgXCJCYjRcIiwgXCJENVwiXSwgWzQsIDMsIDIsIDFdKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlcywgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBpZiAoaXNBcnJheShkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGFzc2VydChpc0FycmF5KG5vdGVzKSwgXCJJZiB0aGUgZHVyYXRpb24gaXMgYW4gYXJyYXksIHRoZSBub3RlcyBtdXN0IGFsc28gYmUgYW4gYXJyYXlcIik7XG4gICAgICAgICAgICBub3RlcyA9IG5vdGVzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub3Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBkdXJhdGlvbltNYXRoLm1pbihpLCBkdXJhdGlvbi5sZW5ndGggLSAxKV07XG4gICAgICAgICAgICAgICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gdGhpcy50b1NlY29uZHMoZCk7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGR1cmF0aW9uU2Vjb25kcyA+IDAsIFwiVGhlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3Rlc1tpXSwgY29tcHV0ZWRUaW1lICsgZHVyYXRpb25TZWNvbmRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGFzc2VydChkdXJhdGlvblNlY29uZHMgPiAwLCBcIlRoZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlcywgY29tcHV0ZWRUaW1lICsgZHVyYXRpb25TZWNvbmRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IGEgbWVtYmVyL2F0dHJpYnV0ZSBvZiB0aGUgdm9pY2VzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHNldCBhbGwgb2YgdGhlIHZvaWNlcyB1c2luZyBhbiBvcHRpb25zIG9iamVjdCBmb3IgdGhlIHN5bnRoIHR5cGVcbiAgICAgKiBwb2x5LnNldCh7XG4gICAgICogXHRlbnZlbG9wZToge1xuICAgICAqIFx0XHRhdHRhY2s6IDAuMjVcbiAgICAgKiBcdH1cbiAgICAgKiB9KTtcbiAgICAgKiBwb2x5LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQmIzXCIsIDAuMik7XG4gICAgICovXG4gICAgc2V0KG9wdGlvbnMpIHtcbiAgICAgICAgLy8gcmVtb3ZlIG9wdGlvbnMgd2hpY2ggYXJlIGNvbnRyb2xsZWQgYnkgdGhlIFBvbHlTeW50aFxuICAgICAgICBjb25zdCBzYW5pdGl6ZWRPcHRpb25zID0gb21pdEZyb21PYmplY3Qob3B0aW9ucywgW1wib25zaWxlbmNlXCIsIFwiY29udGV4dFwiXSk7XG4gICAgICAgIC8vIHN0b3JlIGFsbCBvZiB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBkZWVwTWVyZ2UodGhpcy5vcHRpb25zLCBzYW5pdGl6ZWRPcHRpb25zKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLmZvckVhY2godm9pY2UgPT4gdm9pY2Uuc2V0KHNhbml0aXplZE9wdGlvbnMpKTtcbiAgICAgICAgdGhpcy5fZHVtbXlWb2ljZS5zZXQoc2FuaXRpemVkT3B0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kdW1teVZvaWNlLmdldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgYWxsIHRoZSBjdXJyZW50bHkgYWN0aXZlIHZvaWNlcyBpbW1lZGlhdGVseS5cbiAgICAgKiBVc2VmdWwgZm9yIHNpbGVuY2luZyB0aGUgc3ludGguXG4gICAgICovXG4gICAgcmVsZWFzZUFsbCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMuZm9yRWFjaCgoeyB2b2ljZSB9KSA9PiB7XG4gICAgICAgICAgICB2b2ljZS50cmlnZ2VyUmVsZWFzZShjb21wdXRlZFRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlWb2ljZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5mb3JFYWNoKHYgPT4gdi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fYXZhaWxhYmxlVm9pY2VzID0gW107XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhckludGVydmFsKHRoaXMuX2djVGltZW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBvbHlTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXJzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBmdG9tZiwgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTm90ZSwgaXNOdW1iZXIgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuLi9pbnN0cnVtZW50L0luc3RydW1lbnRcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQYXNzIGluIGFuIG9iamVjdCB3aGljaCBtYXBzIHRoZSBub3RlJ3MgcGl0Y2ggb3IgbWlkaSB2YWx1ZSB0byB0aGUgdXJsLFxuICogdGhlbiB5b3UgY2FuIHRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBvZiB0aGF0IG5vdGUgbGlrZSBvdGhlciBpbnN0cnVtZW50cy5cbiAqIEJ5IGF1dG9tYXRpY2FsbHkgcmVwaXRjaGluZyB0aGUgc2FtcGxlcywgaXQgaXMgcG9zc2libGUgdG8gcGxheSBwaXRjaGVzIHdoaWNoXG4gKiB3ZXJlIG5vdCBleHBsaWNpdGx5IGluY2x1ZGVkIHdoaWNoIGNhbiBzYXZlIGxvYWRpbmcgdGltZS5cbiAqXG4gKiBGb3Igc2FtcGxlIG9yIGJ1ZmZlciBwbGF5YmFjayB3aGVyZSByZXBpdGNoaW5nIGlzIG5vdCBuZWNlc3NhcnksXG4gKiB1c2UgW1tQbGF5ZXJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzYW1wbGVyID0gbmV3IFRvbmUuU2FtcGxlcih7XG4gKiBcdHVybHM6IHtcbiAqIFx0XHRBMTogXCJBMS5tcDNcIixcbiAqIFx0XHRBMjogXCJBMi5tcDNcIixcbiAqIFx0fSxcbiAqIFx0YmFzZVVybDogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vXCIsXG4gKiBcdG9ubG9hZDogKCkgPT4ge1xuICogXHRcdHNhbXBsZXIudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzFcIiwgXCJFMVwiLCBcIkcxXCIsIFwiQjFcIl0sIDAuNSk7XG4gKiBcdH1cbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTYW1wbGVyIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNhbXBsZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCIsIFwiYmFzZVVybFwiXSwgXCJ1cmxzXCIpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTYW1wbGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2JqZWN0IG9mIGFsbCBjdXJyZW50bHkgcGxheWluZyBCdWZmZXJTb3VyY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2FtcGxlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIik7XG4gICAgICAgIGNvbnN0IHVybE1hcCA9IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhvcHRpb25zLnVybHMpLmZvckVhY2goKG5vdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdGVOdW1iZXIgPSBwYXJzZUludChub3RlLCAxMCk7XG4gICAgICAgICAgICBhc3NlcnQoaXNOb3RlKG5vdGUpXG4gICAgICAgICAgICAgICAgfHwgKGlzTnVtYmVyKG5vdGVOdW1iZXIpICYmIGlzRmluaXRlKG5vdGVOdW1iZXIpKSwgYHVybCBrZXkgaXMgbmVpdGhlciBhIG5vdGUgb3IgbWlkaSBwaXRjaDogJHtub3RlfWApO1xuICAgICAgICAgICAgaWYgKGlzTm90ZShub3RlKSkge1xuICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIG5vdGUgbmFtZSB0byBNSURJXG4gICAgICAgICAgICAgICAgY29uc3QgbWlkID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICAgICAgdXJsTWFwW21pZF0gPSBvcHRpb25zLnVybHNbbm90ZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc051bWJlcihub3RlTnVtYmVyKSAmJiBpc0Zpbml0ZShub3RlTnVtYmVyKSkge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBpZiBpdCdzIG51bWJlcnMgYXNzdW1lIGl0J3MgbWlkaVxuICAgICAgICAgICAgICAgIHVybE1hcFtub3RlTnVtYmVyXSA9IG9wdGlvbnMudXJsc1tub3RlTnVtYmVyXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgVG9uZUF1ZGlvQnVmZmVycyh7XG4gICAgICAgICAgICB1cmxzOiB1cmxNYXAsXG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgYmFzZVVybDogb3B0aW9ucy5iYXNlVXJsLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLmN1cnZlID0gb3B0aW9ucy5jdXJ2ZTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFjayBpZiBpdCdzIGFscmVhZHkgbG9hZGVkXG4gICAgICAgIGlmICh0aGlzLl9idWZmZXJzLmxvYWRlZCkge1xuICAgICAgICAgICAgLy8gaW52b2tlIG9ubG9hZCBkZWZlcnJlZFxuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihvcHRpb25zLm9ubG9hZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFjazogMCxcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBjdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHJlbGVhc2U6IDAuMSxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBpbiBzdGVwcyBiZXR3ZWVuIHRoZSBnaXZlbiBtaWRpIG5vdGUgYXQgdGhlIGNsb3NldHMgc2FtcGxlLlxuICAgICAqL1xuICAgIF9maW5kQ2xvc2VzdChtaWRpKSB7XG4gICAgICAgIC8vIHNlYXJjaGVzIHdpdGhpbiA4IG9jdGF2ZXMgb2YgdGhlIGdpdmVuIG1pZGkgbm90ZVxuICAgICAgICBjb25zdCBNQVhfSU5URVJWQUwgPSA5NjtcbiAgICAgICAgbGV0IGludGVydmFsID0gMDtcbiAgICAgICAgd2hpbGUgKGludGVydmFsIDwgTUFYX0lOVEVSVkFMKSB7XG4gICAgICAgICAgICAvLyBjaGVjayBhYm92ZSBhbmQgYmVsb3dcbiAgICAgICAgICAgIGlmICh0aGlzLl9idWZmZXJzLmhhcyhtaWRpICsgaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC1pbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgLSBpbnRlcnZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnRlcnZhbCsrO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gYXZhaWxhYmxlIGJ1ZmZlcnMgZm9yIG5vdGU6ICR7bWlkaX1gKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcGxheSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBXaGVuIHRvIHBsYXkgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0byBwbGF5IHRoZSBzYW1wbGUgYmFjay5cbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaUZsb2F0ID0gZnRvbWYobmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9GcmVxdWVuY3koKSk7XG4gICAgICAgICAgICBjb25zdCBtaWRpID0gTWF0aC5yb3VuZChtaWRpRmxvYXQpO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyID0gbWlkaUZsb2F0IC0gbWlkaTtcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIGNsb3Nlc3Qgbm90ZSBwaXRjaFxuICAgICAgICAgICAgY29uc3QgZGlmZmVyZW5jZSA9IHRoaXMuX2ZpbmRDbG9zZXN0KG1pZGkpO1xuICAgICAgICAgICAgY29uc3QgY2xvc2VzdE5vdGUgPSBtaWRpIC0gZGlmZmVyZW5jZTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcnMuZ2V0KGNsb3Nlc3ROb3RlKTtcbiAgICAgICAgICAgIGNvbnN0IHBsYXliYWNrUmF0ZSA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhkaWZmZXJlbmNlICsgcmVtYWluZGVyKTtcbiAgICAgICAgICAgIC8vIHBsYXkgdGhhdCBub3RlXG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICAgICAgdXJsOiBidWZmZXIsXG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGN1cnZlOiB0aGlzLmN1cnZlLFxuICAgICAgICAgICAgICAgIGZhZGVJbjogdGhpcy5hdHRhY2ssXG4gICAgICAgICAgICAgICAgZmFkZU91dDogdGhpcy5yZWxlYXNlLFxuICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KHRpbWUsIDAsIGJ1ZmZlci5kdXJhdGlvbiAvIHBsYXliYWNrUmF0ZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICAgICAgaWYgKCFpc0FycmF5KHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2V0KG1pZGksIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpLnB1c2goc291cmNlKTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBpdCB3aGVuIGl0J3MgZG9uZVxuICAgICAgICAgICAgc291cmNlLm9uZW5kZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMgJiYgdGhpcy5fYWN0aXZlU291cmNlcy5oYXMobWlkaSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlcyA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHNvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSAgbm90ZXNcdFRoZSBub3RlIHRvIHJlbGVhc2UsIG9yIGFuIGFycmF5IG9mIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgXHRXaGVuIHRvIHJlbGVhc2UgdGhlIG5vdGUuXG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCBub3RlcywgdGltZSk7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaSA9IG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgbm90ZVxuICAgICAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMuaGFzKG1pZGkpICYmIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKTtcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgICAgICAgICAgc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2V0KG1pZGksIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlIGFsbCBjdXJyZW50bHkgYWN0aXZlIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgXHRXaGVuIHRvIHJlbGVhc2UgdGhlIG5vdGVzLlxuICAgICAqL1xuICAgIHJlbGVhc2VBbGwodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZXMgPT4ge1xuICAgICAgICAgICAgd2hpbGUgKHNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIHNvdXJjZS5zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBhdHRhY2sgcGhhc2UsIHRoZW4gYWZ0ZXIgdGhlIGR1cmF0aW9uLCBpbnZva2UgdGhlIHJlbGVhc2UuXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcGxheSBhbmQgcmVsZWFzZSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBUaGUgdGltZSB0aGUgbm90ZSBzaG91bGQgYmUgaGVsZFxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgV2hlbiB0byBzdGFydCB0aGUgYXR0YWNrXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGF0dGFja1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGVzLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBpZiAoaXNBcnJheShkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGFzc2VydChpc0FycmF5KG5vdGVzKSwgXCJub3RlcyBtdXN0IGJlIGFuIGFycmF5IHdoZW4gZHVyYXRpb24gaXMgYXJyYXlcIik7XG4gICAgICAgICAgICBub3Rlcy5mb3JFYWNoKChub3RlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBkdXJhdGlvbltNYXRoLm1pbihpbmRleCwgZHVyYXRpb24ubGVuZ3RoIC0gMSldO1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZSwgY29tcHV0ZWRUaW1lICsgdGhpcy50b1NlY29uZHMoZCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzLCBjb21wdXRlZFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBub3RlIHRvIHRoZSBzYW1wbGVyLlxuICAgICAqIEBwYXJhbSAgbm90ZSAgICAgIFRoZSBidWZmZXIncyBwaXRjaC5cbiAgICAgKiBAcGFyYW0gIHVybCAgRWl0aGVyIHRoZSB1cmwgb2YgdGhlIGJ1ZmZlciwgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBhZGQobm90ZSwgdXJsLCBjYWxsYmFjaykge1xuICAgICAgICBhc3NlcnQoaXNOb3RlKG5vdGUpIHx8IGlzRmluaXRlKG5vdGUpLCBgbm90ZSBtdXN0IGJlIGEgcGl0Y2ggb3IgbWlkaTogJHtub3RlfWApO1xuICAgICAgICBpZiAoaXNOb3RlKG5vdGUpKSB7XG4gICAgICAgICAgICAvLyBjb252ZXJ0IHRoZSBub3RlIG5hbWUgdG8gTUlESVxuICAgICAgICAgICAgY29uc3QgbWlkID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChtaWQsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChub3RlLCB1cmwsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5sb2FkZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZXMgPT4ge1xuICAgICAgICAgICAgc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UuZGlzcG9zZSgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBTYW1wbGVyLnByb3RvdHlwZSwgXCJhdHRhY2tcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgU2FtcGxlci5wcm90b3R5cGUsIFwicmVsZWFzZVwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2FtcGxlci5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BTVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EdW9TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRk1TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTWV0YWxTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTWVtYnJhbmVTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTW9ub1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Ob2lzZVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QbHVja1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Qb2x5U3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NhbXBsZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N5bnRoXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgXCIuLi9jb3JlL2Nsb2NrL1RyYW5zcG9ydFwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNCb29sZWFuLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRvbmVFdmVudCBhYnN0cmFjdHMgYXdheSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlIGFuZCBwcm92aWRlcyBhIHNjaGVkdWxhYmxlXG4gKiBjYWxsYmFjayBmb3IgYSBzaW5nbGUgb3IgcmVwZWF0YWJsZSBldmVudHMgYWxvbmcgdGhlIHRpbWVsaW5lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGNob3JkRXZlbnQgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKCh0aW1lLCBjaG9yZCkgPT4ge1xuICogXHQvLyB0aGUgY2hvcmQgYXMgd2VsbCBhcyB0aGUgZXhhY3QgdGltZSBvZiB0aGUgZXZlbnRcbiAqIFx0Ly8gYXJlIHBhc3NlZCBpbiBhcyBhcmd1bWVudHMgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uXG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKGNob3JkLCAwLjUsIHRpbWUpO1xuICogfSksIFtcIkQ0XCIsIFwiRTRcIiwgXCJGNFwiXSk7XG4gKiAvLyBzdGFydCB0aGUgY2hvcmQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdHJhbnNwb3J0IHRpbWVsaW5lXG4gKiBjaG9yZEV2ZW50LnN0YXJ0KCk7XG4gKiAvLyBsb29wIGl0IGV2ZXJ5IG1lYXN1cmUgZm9yIDggbWVhc3VyZXNcbiAqIGNob3JkRXZlbnQubG9vcCA9IDg7XG4gKiBjaG9yZEV2ZW50Lmxvb3BFbmQgPSBcIjFtXCI7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVFdmVudCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lRXZlbnRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWNrcyB0aGUgc2NoZWR1bGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGRlbGF5IHRpbWUgZnJvbSB3aGVuIHRoZSBldmVudCBpcyBzY2hlZHVsZWQgdG8gc3RhcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhvcHRpb25zLmxvb3BTdGFydCk7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5sb29wRW5kKTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gb3B0aW9ucy5wcm9iYWJpbGl0eTtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSBvcHRpb25zLmh1bWFuaXplO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIGV2ZW50cyBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIGh1bWFuaXplOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogXCIxbVwiLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogMSxcbiAgICAgICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmVcbiAgICAgKiB3aXRoIHRoZSB1cGRhdGVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gYWZ0ZXIgT25seSByZXNjaGVkdWxlcyBldmVudHMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgX3Jlc2NoZWR1bGVFdmVudHMoYWZ0ZXIgPSAtMSkge1xuICAgICAgICAvLyBpZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgc2NoZWR1bGVzIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKGFmdGVyLCBldmVudCA9PiB7XG4gICAgICAgICAgICBsZXQgZHVyYXRpb247XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmlkICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRUaWNrID0gZXZlbnQudGltZSArIE1hdGgucm91bmQodGhpcy5zdGFydE9mZnNldCAvIHRoaXMuX3BsYXliYWNrUmF0ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3AgPT09IHRydWUgfHwgaXNOdW1iZXIodGhpcy5fbG9vcCkgJiYgdGhpcy5fbG9vcCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBJbmZpbml0eTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTnVtYmVyKHRoaXMuX2xvb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9ICh0aGlzLl9sb29wKSAqIHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRFdmVudCA9IHRoaXMuX3N0YXRlLmdldEFmdGVyKHN0YXJ0VGljayk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0RXZlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gTWF0aC5taW4oZHVyYXRpb24sIG5leHRFdmVudC50aW1lIC0gc3RhcnRUaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZHVyYXRpb24gIT09IEluZmluaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzY2hlZHVsZSBhIHN0b3Agc2luY2UgaXQncyBmaW5pdGUgZHVyYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBzdGFydFRpY2sgKyBkdXJhdGlvbiArIDEsIHsgaWQ6IC0xIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbCA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCkpO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fdGljay5iaW5kKHRoaXMpLCBpbnRlcnZhbCwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpY2spLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fdGljay5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGljaykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBub3RlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdGFydCBmcm9tIHRoZSBzY2hlZHVsZWQgc3RhcnQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KG9mZnNldCkge1xuICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IG9mZnNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHByb2JhYmlsaXR5IG9mIHRoZSBub3RlcyBiZWluZyB0cmlnZ2VyZWQuXG4gICAgICovXG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgc2V0IHRvIHRydWUsIHdpbGwgYXBwbHkgc21hbGwgcmFuZG9tIHZhcmlhdGlvblxuICAgICAqIHRvIHRoZSBjYWxsYmFjayB0aW1lLiBJZiB0aGUgdmFsdWUgaXMgZ2l2ZW4gYXMgYSB0aW1lLCBpdCB3aWxsIHJhbmRvbWl6ZVxuICAgICAqIGJ5IHRoYXQgYW1vdW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZXZlbnQgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKTtcbiAgICAgKiBldmVudC5odW1hbml6ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0YXJ0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5hZGQoe1xuICAgICAgICAgICAgICAgIGlkOiAtMSxcbiAgICAgICAgICAgICAgICBzdGF0ZTogXCJzdGFydGVkXCIsXG4gICAgICAgICAgICAgICAgdGltZTogdGlja3MsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHModGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBFdmVudCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIGV2ZW50IHNob3VsZCBzdG9wLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLmNhbmNlbCh0aW1lKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGlja3MsIHsgaWQ6IC0xIH0pO1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX3N0YXRlLmdldEJlZm9yZSh0aWNrcyk7XG4gICAgICAgICAgICBsZXQgcmVzY2hlZHVsVGltZSA9IHRpY2tzO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzRXZlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXNjaGVkdWxUaW1lID0gcHJldmlvdXNFdmVudC50aW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyhyZXNjaGVkdWxUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggZXZlbnRzIHdpbGwgYmUgY2FuY2VsLlxuICAgICAqL1xuICAgIGNhbmNlbCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSBkZWZhdWx0QXJnKHRpbWUsIC1JbmZpbml0eSk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoRnJvbSh0aWNrcywgZXZlbnQgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihldmVudC5pZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGlja3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGludm9rZXIuIEFsc29cbiAgICAgKiBjaGVja3MgaWYgdGhlIEV2ZW50IGlzIGRvbmUgcGxheWluZ1xuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBfdGljayh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvYmFiaWxpdHkgPCAxICYmIE1hdGgucmFuZG9tKCkgPiB0aGlzLnByb2JhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaHVtYW5pemUpIHtcbiAgICAgICAgICAgICAgICBsZXQgdmFyaWF0aW9uID0gMC4wMjtcbiAgICAgICAgICAgICAgICBpZiAoIWlzQm9vbGVhbih0aGlzLmh1bWFuaXplKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXJpYXRpb24gPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmh1bWFuaXplKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGltZSArPSAoTWF0aC5yYW5kb20oKSAqIDIgLSAxKSAqIHZhcmlhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGhpcy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkdXJhdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBfZ2V0TG9vcER1cmF0aW9uKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCkgLyB0aGlzLl9wbGF5YmFja1JhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgbm90ZSBzaG91bGQgbG9vcCBvciBub3RcbiAgICAgKiBiZXR3ZWVuIFRvbmVFdmVudC5sb29wU3RhcnQgYW5kXG4gICAgICogVG9uZUV2ZW50Lmxvb3BFbmQuIElmIHNldCB0byB0cnVlLFxuICAgICAqIHRoZSBldmVudCB3aWxsIGxvb3AgaW5kZWZpbml0ZWx5LFxuICAgICAqIGlmIHNldCB0byBhIG51bWJlciBncmVhdGVyIHRoYW4gMVxuICAgICAqIGl0IHdpbGwgcGxheSBhIHNwZWNpZmljIG51bWJlciBvZlxuICAgICAqIHRpbWVzLCBpZiBzZXQgdG8gZmFsc2UsIDAgb3IgMSwgdGhlXG4gICAgICogcGFydCB3aWxsIG9ubHkgcGxheSBvbmNlLlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbm90ZS4gRGVmYXVsdHMgdG8gMS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vdGUgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKTtcbiAgICAgKiBub3RlLmxvb3AgPSB0cnVlO1xuICAgICAqIC8vIHJlcGVhdCB0aGUgbm90ZSB0d2ljZSBhcyBmYXN0XG4gICAgICogbm90ZS5wbGF5YmFja1JhdGUgPSAyO1xuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wRW5kIHBvaW50IGlzIHRoZSB0aW1lIHRoZSBldmVudCB3aWxsIGxvb3BcbiAgICAgKiBpZiBUb25lRXZlbnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGxvb3BFbmQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHdoZW4gdGhlIGxvb3Agc2hvdWxkIHN0YXJ0LlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHByb2dyZXNzIG9mIHRoZSBsb29wIGludGVydmFsLlxuICAgICAqIFJldHVybnMgMCBpZiB0aGUgZXZlbnQgaXMgbm90IHN0YXJ0ZWQgeWV0IG9yXG4gICAgICogaXQgaXMgbm90IHNldCB0byBsb29wLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcztcbiAgICAgICAgICAgIGNvbnN0IGxhc3RFdmVudCA9IHRoaXMuX3N0YXRlLmdldCh0aWNrcyk7XG4gICAgICAgICAgICBpZiAobGFzdEV2ZW50ICE9PSBudWxsICYmIGxhc3RFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsb29wRHVyYXRpb24gPSB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9ICh0aWNrcyAtIGxhc3RFdmVudC50aW1lKSAlIGxvb3BEdXJhdGlvbjtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvZ3Jlc3MgLyBsb29wRHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lRXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUV2ZW50IH0gZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogTG9vcCBjcmVhdGVzIGEgbG9vcGVkIGNhbGxiYWNrIGF0IHRoZVxuICogc3BlY2lmaWVkIGludGVydmFsLiBUaGUgY2FsbGJhY2sgY2FuIGJlXG4gKiBzdGFydGVkLCBzdG9wcGVkIGFuZCBzY2hlZHVsZWQgYWxvbmdcbiAqIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBsb29wID0gbmV3IFRvbmUuTG9vcCgodGltZSkgPT4ge1xuICogXHQvLyB0cmlnZ2VyZWQgZXZlcnkgZWlnaHRoIG5vdGUuXG4gKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogfSwgXCI4blwiKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIExvb3AgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMb29wLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJpbnRlcnZhbFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxvb3BcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExvb3AuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImludGVydmFsXCJdKTtcbiAgICAgICAgdGhpcy5fZXZlbnQgPSBuZXcgVG9uZUV2ZW50KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgbG9vcEVuZDogb3B0aW9ucy5pbnRlcnZhbCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogb3B0aW9ucy5wcm9iYWJpbGl0eVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIC8vIHNldCB0aGUgaXRlcmF0aW9uc1xuICAgICAgICB0aGlzLml0ZXJhdGlvbnMgPSBvcHRpb25zLml0ZXJhdGlvbnM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGludGVydmFsOiBcIjRuXCIsXG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIGl0ZXJhdGlvbnM6IEluZmluaXR5LFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IDEsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIGh1bWFuaXplOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGxvb3AgYXQgdGhlIHNwZWNpZmllZCB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RhcnQgdGhlIExvb3AuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxvb3AgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0b3AgdGhlIExvb3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBhZnRlciB3aGljaCBldmVudHMgd2lsbCBiZSBjYW5jZWwuXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuY2FuY2VsKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgZnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIG5vdGVzIHNob3VsZCBiZSBjYWxsZWRcbiAgICAgKiBAcGFyYW0gdGltZSAgVGhlIHRpbWUgdGhlIGV2ZW50IG9jY3Vyc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRlIG9mIHRoZSBMb29wLCBlaXRoZXIgc3RhcnRlZCBvciBzdG9wcGVkLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnN0YXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgYXMgYSB2YWx1ZSBiZXR3ZWVuIDAtMS4gMCwgd2hlbiB0aGUgbG9vcCBpcyBzdG9wcGVkIG9yIGRvbmUgaXRlcmF0aW5nLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnByb2dyZXNzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbG9vcCA9IG5ldyBUb25lLkxvb3AoKTtcbiAgICAgKiBsb29wLmludGVydmFsID0gXCI4blwiOyAvLyBsb29wIGV2ZXJ5IDhuXG4gICAgICovXG4gICAgZ2V0IGludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGludGVydmFsKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lmxvb3BFbmQgPSBpbnRlcnZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIGxvb3AuIFRoZSBub3JtYWwgcGxheWJhY2sgcmF0ZSBpcyAxIChubyBjaGFuZ2UpLlxuICAgICAqIEEgYHBsYXliYWNrUmF0ZWAgb2YgMiB3b3VsZCBiZSB0d2ljZSBhcyBmYXN0LlxuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSYW5kb20gdmFyaWF0aW9uICsvLTAuMDFzIHRvIHRoZSBzY2hlZHVsZWQgdGltZS5cbiAgICAgKiBPciBnaXZlIGl0IGEgdGltZSB2YWx1ZSB3aGljaCBpdCB3aWxsIHJhbmRvbWl6ZSBieS5cbiAgICAgKi9cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9ldmVudC5odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHByb2JhYmx5IG9mIHRoZSBjYWxsYmFjayBiZWluZyBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9ldmVudC5wcm9iYWJpbGl0eSA9IHByb2I7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGluZyB0aGUgTG9vcCBtZWFucyB0aGF0IG5vIGNhbGxiYWNrcyBhcmUgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyBvZiB0aGUgbG9vcC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYEluZmluaXR5YCAobG9vcCBmb3JldmVyKS5cbiAgICAgKi9cbiAgICBnZXQgaXRlcmF0aW9ucygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50Lmxvb3AgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBpdGVyYXRpb25zKGl0ZXJzKSB7XG4gICAgICAgIGlmIChpdGVycyA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50Lmxvb3AgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnQubG9vcCA9IGl0ZXJzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Mb29wLmpzLm1hcCIsImltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNVbmRlZiB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbi8qKlxuICogUGFydCBpcyBhIGNvbGxlY3Rpb24gVG9uZUV2ZW50cyB3aGljaCBjYW4gYmUgc3RhcnRlZC9zdG9wcGVkIGFuZCBsb29wZWQgYXMgYSBzaW5nbGUgdW5pdC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCgodGltZSwgbm90ZSkgPT4ge1xuICogXHQvLyB0aGUgbm90ZXMgZ2l2ZW4gYXMgdGhlIHNlY29uZCBlbGVtZW50IGluIHRoZSBhcnJheVxuICogXHQvLyB3aWxsIGJlIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIFwiOG5cIiwgdGltZSk7XG4gKiB9KSwgW1swLCBcIkMyXCJdLCBbXCIwOjJcIiwgXCJDM1wiXSwgW1wiMDozOjJcIiwgXCJHMlwiXV0pO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gdXNlIGFuIGFycmF5IG9mIG9iamVjdHMgYXMgbG9uZyBhcyB0aGUgb2JqZWN0IGhhcyBhIFwidGltZVwiIGF0dHJpYnV0ZVxuICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKCh0aW1lLCB2YWx1ZSkgPT4ge1xuICogXHQvLyB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGJvdGggdGhlIG5vdGUgYW5kIHRoZSB2ZWxvY2l0eVxuICogXHRzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSh2YWx1ZS5ub3RlLCBcIjhuXCIsIHRpbWUsIHZhbHVlLnZlbG9jaXR5KTtcbiAqIH0pLCBbeyB0aW1lOiAwLCBub3RlOiBcIkMzXCIsIHZlbG9jaXR5OiAwLjkgfSxcbiAqIFx0eyB0aW1lOiBcIjA6MlwiLCBub3RlOiBcIkM0XCIsIHZlbG9jaXR5OiAwLjUgfVxuICogXSkuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYXJ0IGV4dGVuZHMgVG9uZUV2ZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFydFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBldmVudHMgdGhhdCBiZWxvbmcgdG8gdGhpcyBwYXJ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgU2V0KCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIl0pO1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhpbmdzIGFyZSBhc3NpZ25lZCBpbiB0aGUgcmlnaHQgb3JkZXJcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5jcmVhc2luZyA9IHRydWU7XG4gICAgICAgIC8vIGFkZCB0aGUgZXZlbnRzXG4gICAgICAgIG9wdGlvbnMuZXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZXZlbnRbMF0sIGV2ZW50WzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGV2ZW50czogW10sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgV2hlbiB0byBzdGFydCB0aGUgcGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCAgVGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFydCB0byBiZWdpbiBwbGF5aW5nIGF0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wID8gdGhpcy5fbG9vcFN0YXJ0IDogMCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvVGlja3Mob2Zmc2V0KTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG4gICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgIG9mZnNldDogY29tcHV0ZWRPZmZzZXQsXG4gICAgICAgICAgICAgICAgc3RhdGU6IFwic3RhcnRlZFwiLFxuICAgICAgICAgICAgICAgIHRpbWU6IHRpY2tzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydE5vdGUoZXZlbnQsIHRpY2tzLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGV2ZW50IGluIHRoZSBnaXZlbiBldmVudCBhdCB0aGUgY29ycmVjdCB0aW1lIGdpdmVuXG4gICAgICogdGhlIHRpY2tzIGFuZCBvZmZzZXQgYW5kIGxvb3BpbmcuXG4gICAgICogQHBhcmFtICBldmVudFxuICAgICAqIEBwYXJhbSAgdGlja3NcbiAgICAgKiBAcGFyYW0gIG9mZnNldFxuICAgICAqL1xuICAgIF9zdGFydE5vdGUoZXZlbnQsIHRpY2tzLCBvZmZzZXQpIHtcbiAgICAgICAgdGlja3MgLT0gb2Zmc2V0O1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID49IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BFbmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPCBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgaXQgb24gdGhlIG5leHQgbG9vcFxuICAgICAgICAgICAgICAgICAgICB0aWNrcyArPSB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPCB0aGlzLl9sb29wU3RhcnQgJiYgZXZlbnQuc3RhcnRPZmZzZXQgPj0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0YXJ0KG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgIGV2ZW50LnN0YXJ0KG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KG9mZnNldCkge1xuICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5zdGFydE9mZnNldCArPSB0aGlzLl9zdGFydE9mZnNldDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0b3AgdGhlIHBhcnQuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGlja3MpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGlja3MpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50LnN0b3AodGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0L1NldCBhbiBFdmVudCdzIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIElmIGEgdmFsdWUgaXMgcGFzc2VkIGluIGFuZCBubyBldmVudCBleGlzdHMgYXRcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZSwgb25lIHdpbGwgYmUgY3JlYXRlZCB3aXRoIHRoYXQgdmFsdWUuXG4gICAgICogSWYgdHdvIGV2ZW50cyBhcmUgYXQgdGhlIHNhbWUgdGltZSwgdGhlIGZpcnN0IG9uZSB3aWxsXG4gICAgICogYmUgcmV0dXJuZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgpO1xuICAgICAqIHBhcnQuYXQoXCIxbVwiKTsgLy8gcmV0dXJucyB0aGUgcGFydCBhdCB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIHBhcnQuYXQoXCIybVwiLCBcIkMyXCIpOyAvLyBzZXQgdGhlIHZhbHVlIGF0IFwiMm1cIiB0byBDMi5cbiAgICAgKiAvLyBpZiBhbiBldmVudCBkaWRuJ3QgZXhpc3QgYXQgdGhhdCB0aW1lLCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IHRvIGdldCBvciBzZXQuXG4gICAgICogQHBhcmFtIHZhbHVlIElmIGEgdmFsdWUgaXMgcGFzc2VkIGluLCB0aGUgdmFsdWUgb2YgdGhlIGV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lIHdpbGwgYmUgc2V0IHRvIGl0LlxuICAgICAqL1xuICAgIGF0KHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHRpbWVJblRpY2tzID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKTtcbiAgICAgICAgY29uc3QgdGlja1RpbWUgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIDEpLnRvU2Vjb25kcygpO1xuICAgICAgICBjb25zdCBpdGVyYXRvciA9IHRoaXMuX2V2ZW50cy52YWx1ZXMoKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgd2hpbGUgKCFyZXN1bHQuZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnModGltZUluVGlja3MgLSBldmVudC5zdGFydE9mZnNldCkgPCB0aWNrVGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB0aGVyZSB3YXMgbm8gZXZlbnQgYXQgdGhhdCB0aW1lLCBjcmVhdGUgb25lXG4gICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLmFkZCh0aW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICAvLyByZXR1cm4gdGhlIG5ldyBldmVudFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXQodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGQodGltZSwgdmFsdWUpIHtcbiAgICAgICAgLy8gZXh0cmFjdCB0aGUgcGFyYW1ldGVyc1xuICAgICAgICBpZiAodGltZSBpbnN0YW5jZW9mIE9iamVjdCAmJiBSZWZsZWN0Lmhhcyh0aW1lLCBcInRpbWVcIikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGltZTtcbiAgICAgICAgICAgIHRpbWUgPSB2YWx1ZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBsZXQgZXZlbnQ7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFRvbmVFdmVudCkge1xuICAgICAgICAgICAgZXZlbnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIGV2ZW50LmNhbGxiYWNrID0gdGhpcy5fdGljay5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZXZlbnQgPSBuZXcgVG9uZUV2ZW50KHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fdGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBzdGFydCBvZmZzZXRcbiAgICAgICAgZXZlbnQuc3RhcnRPZmZzZXQgPSB0aWNrcztcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgdmFsdWVzXG4gICAgICAgIGV2ZW50LnNldCh7XG4gICAgICAgICAgICBodW1hbml6ZTogdGhpcy5odW1hbml6ZSxcbiAgICAgICAgICAgIGxvb3A6IHRoaXMubG9vcCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IHRoaXMubG9vcEVuZCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5sb29wU3RhcnQsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMucGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IHRoaXMucHJvYmFiaWxpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKGV2ZW50KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG5vdGUgaWYgaXQgc2hvdWxkIGJlIHBsYXllZCByaWdodCBub3dcbiAgICAgICAgdGhpcy5fcmVzdGFydEV2ZW50KGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIGdpdmVuIGV2ZW50XG4gICAgICovXG4gICAgX3Jlc3RhcnRFdmVudChldmVudCkge1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoKChzdGF0ZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoc3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydE5vdGUoZXZlbnQsIHN0YXRlRXZlbnQudGltZSwgc3RhdGVFdmVudC5vZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gc3RvcCB0aGUgbm90ZVxuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3AobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBzdGF0ZUV2ZW50LnRpbWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbW92ZSh0aW1lLCB2YWx1ZSkge1xuICAgICAgICAvLyBleHRyYWN0IHRoZSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmIChpc09iamVjdCh0aW1lKSAmJiB0aW1lLmhhc093blByb3BlcnR5KFwidGltZVwiKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGltZSA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID09PSB0aW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5kZWYodmFsdWUpIHx8IChpc0RlZmluZWQodmFsdWUpICYmIGV2ZW50LnZhbHVlID09PSB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmRlbGV0ZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFsbCBvZiB0aGUgbm90ZXMgZnJvbSB0aGUgZ3JvdXAuXG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4gZXZlbnQuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgc2NoZWR1bGVkIHN0YXRlIGNoYW5nZSBldmVudHM6IGkuZS4gXCJzdGFydFwiIGFuZCBcInN0b3BcIi5cbiAgICAgKiBAcGFyYW0gYWZ0ZXIgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IGV2ZW50LmNhbmNlbChhZnRlcikpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy50b1RpY2tzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKi9cbiAgICBfZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgUGFydCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5fZm9yRWFjaChjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXR0cmlidXRlIG9mIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICogQHBhcmFtICBhdHRyICB0aGUgYXR0cmlidXRlIHRvIHNldFxuICAgICAqIEBwYXJhbSAgdmFsdWUgICAgICBUaGUgdmFsdWUgdG8gc2V0IGl0IHRvXG4gICAgICovXG4gICAgX3NldEFsbChhdHRyLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50W2F0dHJdID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCB0aWNrIG1ldGhvZFxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBfdGljayh0aW1lLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSkge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lIGlmIHRoZSBldmVudCBzaG91bGQgYmUgY3VycmVudGx5IGxvb3BpbmdcbiAgICAgKiBnaXZlbiB0aGUgbG9vcCBib3VuZHJpZXMgb2YgdGhpcyBQYXJ0LlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBldmVudCB0byB0ZXN0XG4gICAgICovXG4gICAgX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9sb29wICYmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCB8fCBldmVudC5zdGFydE9mZnNldCA+PSB0aGlzLl9sb29wRW5kKSkge1xuICAgICAgICAgICAgZXZlbnQuY2FuY2VsKDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXRlID09PSBcInN0b3BwZWRcIikge1xuICAgICAgICAgICAgLy8gcmVzY2hlZHVsZSBpdCBpZiBpdCdzIHN0b3BwZWRcbiAgICAgICAgICAgIHRoaXMuX3Jlc3RhcnRFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gcHJvYjtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwicHJvYmFiaWxpdHlcIiwgcHJvYik7XG4gICAgfVxuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2h1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2h1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJodW1hbml6ZVwiLCB2YXJpYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcGFydCBzaG91bGQgbG9vcCBvciBub3RcbiAgICAgKiBiZXR3ZWVuIFBhcnQubG9vcFN0YXJ0IGFuZFxuICAgICAqIFBhcnQubG9vcEVuZC4gSWYgc2V0IHRvIHRydWUsXG4gICAgICogdGhlIHBhcnQgd2lsbCBsb29wIGluZGVmaW5pdGVseSxcbiAgICAgKiBpZiBzZXQgdG8gYSBudW1iZXIgZ3JlYXRlciB0aGFuIDFcbiAgICAgKiBpdCB3aWxsIHBsYXkgYSBzcGVjaWZpYyBudW1iZXIgb2ZcbiAgICAgKiB0aW1lcywgaWYgc2V0IHRvIGZhbHNlLCAwIG9yIDEsIHRoZVxuICAgICAqIHBhcnQgd2lsbCBvbmx5IHBsYXkgb25jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCk7XG4gICAgICogLy8gbG9vcCB0aGUgcGFydCA4IHRpbWVzXG4gICAgICogcGFydC5sb29wID0gODtcbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fbG9vcCA9IGxvb3A7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG4gICAgICAgICAgICBldmVudC5sb29wRW5kID0gdGhpcy5sb29wRW5kO1xuICAgICAgICAgICAgZXZlbnQubG9vcCA9IGxvb3A7XG4gICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcEVuZCBwb2ludCBkZXRlcm1pbmVzIHdoZW4gaXQgd2lsbFxuICAgICAqIGxvb3AgaWYgUGFydC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MobG9vcEVuZCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcFN0YXJ0IHBvaW50IGRldGVybWluZXMgd2hlbiBpdCB3aWxsXG4gICAgICogbG9vcCBpZiBQYXJ0Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wU3RhcnQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3MobG9vcFN0YXJ0KTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3BTdGFydCA9IHRoaXMubG9vcFN0YXJ0O1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBwYXJ0XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuX3NldEFsbChcInBsYXliYWNrUmF0ZVwiLCByYXRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBzY2hlZHVsZWQgbm90ZXMgaW4gdGhlIHBhcnQuXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cy5zaXplO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFydC5qcy5tYXAiLCJpbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBTdGFydCBhdCB0aGUgZmlyc3QgdmFsdWUgYW5kIGdvIHVwIHRvIHRoZSBsYXN0XG4gKi9cbmZ1bmN0aW9uKiB1cFBhdHRlcm5HZW4odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPCB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaW5kZXgrKztcbiAgICB9XG59XG4vKipcbiAqIFN0YXJ0IGF0IHRoZSBsYXN0IHZhbHVlIGFuZCBnbyBkb3duIHRvIDBcbiAqL1xuZnVuY3Rpb24qIGRvd25QYXR0ZXJuR2VuKHZhbHVlcykge1xuICAgIGxldCBpbmRleCA9IHZhbHVlcy5sZW5ndGggLSAxO1xuICAgIHdoaWxlIChpbmRleCA+PSAwKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaW5kZXgtLTtcbiAgICB9XG59XG4vKipcbiAqIEluZmluaXRlbHkgeWllbGQgdGhlIGdlbmVyYXRvclxuICovXG5mdW5jdGlvbiogaW5maW5pdGVHZW4odmFsdWVzLCBnZW4pIHtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICB5aWVsZCogZ2VuKHZhbHVlcyk7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgaW5kZXggaXMgaW4gdGhlIGdpdmVuIHJhbmdlXG4gKi9cbmZ1bmN0aW9uIGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcykge1xuICAgIHJldHVybiBjbGFtcChpbmRleCwgMCwgdmFsdWVzLmxlbmd0aCAtIDEpO1xufVxuLyoqXG4gKiBBbHRlcm5hdGUgYmV0d2VlbiB0d28gZ2VuZXJhdG9yc1xuICovXG5mdW5jdGlvbiogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCBkaXJlY3Rpb25VcCkge1xuICAgIGxldCBpbmRleCA9IGRpcmVjdGlvblVwID8gMCA6IHZhbHVlcy5sZW5ndGggLSAxO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaWYgKGRpcmVjdGlvblVwKSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IHZhbHVlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uVXAgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4LS07XG4gICAgICAgICAgICBpZiAoaW5kZXggPD0gMCkge1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvblVwID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogU3RhcnRpbmcgZnJvbSB0aGUgYm90dG9tIG1vdmUgdXAgMiwgZG93biAxXG4gKi9cbmZ1bmN0aW9uKiBqdW1wVXAodmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICBsZXQgc3RlcEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPCB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgc3RlcEluZGV4Kys7XG4gICAgICAgIGluZGV4ICs9IChzdGVwSW5kZXggJSAyID8gMiA6IC0xKTtcbiAgICB9XG59XG4vKipcbiAqIFN0YXJ0aW5nIGZyb20gdGhlIHRvcCBtb3ZlIGRvd24gMiwgdXAgMVxuICovXG5mdW5jdGlvbioganVtcERvd24odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgbGV0IHN0ZXBJbmRleCA9IDA7XG4gICAgd2hpbGUgKGluZGV4ID49IDApIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBzdGVwSW5kZXgrKztcbiAgICAgICAgaW5kZXggKz0gKHN0ZXBJbmRleCAlIDIgPyAtMiA6IDEpO1xuICAgIH1cbn1cbi8qKlxuICogQ2hvb3NlIGEgcmFuZG9tIGluZGV4IGVhY2ggdGltZVxuICovXG5mdW5jdGlvbiogcmFuZG9tR2VuKHZhbHVlcykge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGNvbnN0IHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tyYW5kb21JbmRleF07XG4gICAgfVxufVxuLyoqXG4gKiBSYW5kb21seSBnbyB0aHJvdWdoIGFsbCBvZiB0aGUgdmFsdWVzIG9uY2UgYmVmb3JlIGNob29zaW5nIGEgbmV3IHJhbmRvbSBvcmRlclxuICovXG5mdW5jdGlvbiogcmFuZG9tT25jZSh2YWx1ZXMpIHtcbiAgICAvLyBjcmVhdGUgYW4gYXJyYXkgb2YgaW5kaWNlc1xuICAgIGNvbnN0IGNvcHkgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb3B5LnB1c2goaSk7XG4gICAgfVxuICAgIHdoaWxlIChjb3B5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gcmFuZG9tIGNob29zZSBhbiBpbmRleCwgYW5kIHRoZW4gcmVtb3ZlIGl0IHNvIGl0J3Mgbm90IGNob3NlbiBhZ2FpblxuICAgICAgICBjb25zdCByYW5kVmFsID0gY29weS5zcGxpY2UoTWF0aC5mbG9vcihjb3B5Lmxlbmd0aCAqIE1hdGgucmFuZG9tKCkpLCAxKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKHJhbmRWYWxbMF0sIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgfVxufVxuLyoqXG4gKiBSYW5kb21seSBjaG9vc2UgdG8gd2FsayB1cCBvciBkb3duIDEgaW5kZXggaW4gdGhlIHZhbHVlcyBhcnJheVxuICovXG5mdW5jdGlvbiogcmFuZG9tV2Fsayh2YWx1ZXMpIHtcbiAgICAvLyByYW5kb21seSBjaG9vc2UgYSBzdGFydGluZyBpbmRleCBpbiB0aGUgdmFsdWVzIGFycmF5XG4gICAgbGV0IGluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdmFsdWVzLmxlbmd0aCk7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICBpbmRleCsrOyAvLyBhdCBib3R0b20gb2YgYXJyYXksIHNvIGZvcmNlIHVwd2FyZCBzdGVwXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT09IHZhbHVlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBpbmRleC0tOyAvLyBhdCB0b3Agb2YgYXJyYXksIHNvIGZvcmNlIGRvd253YXJkIHN0ZXBcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChNYXRoLnJhbmRvbSgpIDwgMC41KSB7IC8vIGVsc2UgY2hvb3NlIHJhbmRvbSBkb3dud2FyZCBvciB1cHdhcmQgc3RlcFxuICAgICAgICAgICAgaW5kZXgtLTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFBhdHRlcm5HZW5lcmF0b3IgcmV0dXJucyBhIGdlbmVyYXRvciB3aGljaCB3aWxsIGl0ZXJhdGUgb3ZlciB0aGUgZ2l2ZW4gYXJyYXlcbiAqIG9mIHZhbHVlcyBhbmQgeWllbGQgdGhlIGl0ZW1zIGFjY29yZGluZyB0byB0aGUgcGFzc2VkIGluIHBhdHRlcm5cbiAqIEBwYXJhbSB2YWx1ZXMgQW4gYXJyYXkgb2YgdmFsdWVzIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIHBhdHRlcm4gVGhlIG5hbWUgb2YgdGhlIHBhdHRlcm4gdXNlIHdoZW4gaXRlcmF0aW5nIG92ZXJcbiAqIEBwYXJhbSBpbmRleCBXaGVyZSB0byBzdGFydCBpbiB0aGUgb2Zmc2V0IG9mIHRoZSB2YWx1ZXMgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uKiBQYXR0ZXJuR2VuZXJhdG9yKHZhbHVlcywgcGF0dGVybiA9IFwidXBcIiwgaW5kZXggPSAwKSB7XG4gICAgLy8gc2FmZWd1YXJkc1xuICAgIGFzc2VydCh2YWx1ZXMubGVuZ3RoID4gMCwgXCJUaGUgYXJyYXkgbXVzdCBoYXZlIG1vcmUgdGhhbiBvbmUgdmFsdWUgaW4gaXRcIik7XG4gICAgc3dpdGNoIChwYXR0ZXJuKSB7XG4gICAgICAgIGNhc2UgXCJ1cFwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgdXBQYXR0ZXJuR2VuKTtcbiAgICAgICAgY2FzZSBcImRvd25cIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGRvd25QYXR0ZXJuR2VuKTtcbiAgICAgICAgY2FzZSBcInVwRG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgdHJ1ZSk7XG4gICAgICAgIGNhc2UgXCJkb3duVXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIGZhbHNlKTtcbiAgICAgICAgY2FzZSBcImFsdGVybmF0ZVVwXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBqdW1wVXApO1xuICAgICAgICBjYXNlIFwiYWx0ZXJuYXRlRG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywganVtcERvd24pO1xuICAgICAgICBjYXNlIFwicmFuZG9tXCI6XG4gICAgICAgICAgICB5aWVsZCogcmFuZG9tR2VuKHZhbHVlcyk7XG4gICAgICAgIGNhc2UgXCJyYW5kb21PbmNlXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCByYW5kb21PbmNlKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbVdhbGtcIjpcbiAgICAgICAgICAgIHlpZWxkKiByYW5kb21XYWxrKHZhbHVlcyk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGF0dGVybkdlbmVyYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBMb29wIH0gZnJvbSBcIi4vTG9vcFwiO1xuaW1wb3J0IHsgUGF0dGVybkdlbmVyYXRvciB9IGZyb20gXCIuL1BhdHRlcm5HZW5lcmF0b3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBhdHRlcm4gYXJwZWdnaWF0ZXMgYmV0d2VlbiB0aGUgZ2l2ZW4gbm90ZXNcbiAqIGluIGEgbnVtYmVyIG9mIHBhdHRlcm5zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBhdHRlcm4gPSBuZXcgVG9uZS5QYXR0ZXJuKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdC8vIHRoZSBvcmRlciBvZiB0aGUgbm90ZXMgcGFzc2VkIGluIGRlcGVuZHMgb24gdGhlIHBhdHRlcm5cbiAqIH0sIFtcIkMyXCIsIFwiRDRcIiwgXCJFNVwiLCBcIkE2XCJdLCBcInVwRG93blwiKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgUGF0dGVybiBleHRlbmRzIExvb3Age1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXR0ZXJuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZXNcIiwgXCJwYXR0ZXJuXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGF0dGVyblwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGF0dGVybi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVzXCIsIFwicGF0dGVyblwiXSk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSBvcHRpb25zLnZhbHVlcztcbiAgICAgICAgdGhpcy5fcGF0dGVybiA9IFBhdHRlcm5HZW5lcmF0b3Iob3B0aW9ucy52YWx1ZXMsIG9wdGlvbnMucGF0dGVybik7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnBhdHRlcm47XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTG9vcC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwYXR0ZXJuOiBcInVwXCIsXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgbm90ZXMgc2hvdWxkIGJlIGNhbGxlZFxuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9wYXR0ZXJuLm5leHQoKTtcbiAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZS52YWx1ZTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aGlzLl92YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhcnJheSBvZiBldmVudHMuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlcztcbiAgICB9XG4gICAgc2V0IHZhbHVlcyh2YWwpIHtcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsO1xuICAgICAgICAvLyByZXNldCB0aGUgcGF0dGVyblxuICAgICAgICB0aGlzLnBhdHRlcm4gPSB0aGlzLl90eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGF0dGVybi5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhdHRlcm4gdHlwZS4gU2VlIFRvbmUuQ3RybFBhdHRlcm4gZm9yIHRoZSBmdWxsIGxpc3Qgb2YgcGF0dGVybnMuXG4gICAgICovXG4gICAgZ2V0IHBhdHRlcm4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgcGF0dGVybihwYXR0ZXJuKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBwYXR0ZXJuO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuID0gUGF0dGVybkdlbmVyYXRvcih0aGlzLl92YWx1ZXMsIHRoaXMuX3R5cGUpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhdHRlcm4uanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzU3RyaW5nIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFBhcnQgfSBmcm9tIFwiLi9QYXJ0XCI7XG5pbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbi8qKlxuICogQSBzZXF1ZW5jZSBpcyBhbiBhbHRlcm5hdGUgbm90YXRpb24gb2YgYSBwYXJ0LiBJbnN0ZWFkXG4gKiBvZiBwYXNzaW5nIGluIGFuIGFycmF5IG9mIFt0aW1lLCBldmVudF0gcGFpcnMsIHBhc3NcbiAqIGluIGFuIGFycmF5IG9mIGV2ZW50cyB3aGljaCB3aWxsIGJlIHNwYWNlZCBhdCB0aGVcbiAqIGdpdmVuIHN1YmRpdmlzaW9uLiBTdWItYXJyYXlzIHdpbGwgc3ViZGl2aWRlIHRoYXQgYmVhdFxuICogYnkgdGhlIG51bWJlciBvZiBpdGVtcyBhcmUgaW4gdGhlIGFycmF5LlxuICogU2VxdWVuY2Ugbm90YXRpb24gaW5zcGlyYXRpb24gZnJvbSBbVGlkYWxdKGh0dHA6Ly95YXh1Lm9yZy90aWRhbC8pXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHNlcSA9IG5ldyBUb25lLlNlcXVlbmNlKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIDAuMSwgdGltZSk7XG4gKiBcdC8vIHN1YmRpdmlzaW9ucyBhcmUgZ2l2ZW4gYXMgc3ViYXJyYXlzXG4gKiB9LCBbXCJDNFwiLCBbXCJFNFwiLCBcIkQ0XCIsIFwiRTRcIl0sIFwiRzRcIiwgW1wiQTRcIiwgXCJHNFwiXV0pLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgU2VxdWVuY2UgZXh0ZW5kcyBUb25lRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTZXF1ZW5jZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCIsIFwic3ViZGl2aXNpb25cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTZXF1ZW5jZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9iamVjdCByZXNwb25zaWJsZSBmb3Igc2NoZWR1bGluZyBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFydCA9IG5ldyBQYXJ0KHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl9zZXFDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHByaXZhdGUgcmVmZXJlbmNlIHRvIGFsbCBvZiB0aGUgc2VxdWVuY2UgcHJveGllc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcHJveGllZCBhcnJheVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzQXJyYXkgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNlcXVlbmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIiwgXCJzdWJkaXZpc2lvblwiXSk7XG4gICAgICAgIHRoaXMuX3N1YmRpdmlzaW9uID0gdGhpcy50b1RpY2tzKG9wdGlvbnMuc3ViZGl2aXNpb24pO1xuICAgICAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuICAgICAgICAvLyBzZXQgYWxsIG9mIHRoZSB2YWx1ZXNcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMucHJvYmFiaWxpdHkgPSBvcHRpb25zLnByb2JhYmlsaXR5O1xuICAgICAgICB0aGlzLmh1bWFuaXplID0gb3B0aW9ucy5odW1hbml6ZTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBbXCJ2YWx1ZVwiXSksIHtcbiAgICAgICAgICAgIGV2ZW50czogW10sXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uOiBcIjhuXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW50ZXJuYWwgY2FsbGJhY2sgZm9yIHdoZW4gYW4gZXZlbnQgaXMgaW52b2tlZFxuICAgICAqL1xuICAgIF9zZXFDYWxsYmFjayh0aW1lLCB2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzZXF1ZW5jZVxuICAgICAqL1xuICAgIGdldCBldmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XG4gICAgfVxuICAgIHNldCBldmVudHMocykge1xuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0FycmF5ID0gcztcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fY3JlYXRlU2VxdWVuY2UodGhpcy5fZXZlbnRzQXJyYXkpO1xuICAgICAgICB0aGlzLl9ldmVudHNVcGRhdGVkKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBXaGVuIHRvIHN0YXJ0IHRoZSBwYXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGluZGV4IHRvIHN0YXJ0IGF0XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3BhcnQuc3RhcnQodGltZSwgb2Zmc2V0ID8gdGhpcy5faW5kZXhUaW1lKG9mZnNldCkgOiBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN1YmRpdmlzaW9uIG9mIHRoZSBzZXF1ZW5jZS4gVGhpcyBjYW4gb25seSBiZVxuICAgICAqIHNldCBpbiB0aGUgY29uc3RydWN0b3IuIFRoZSBzdWJkaXZpc2lvbiBpcyB0aGVcbiAgICAgKiBpbnRlcnZhbCBiZXR3ZWVuIHN1Y2Nlc3NpdmUgc3RlcHMuXG4gICAgICovXG4gICAgZ2V0IHN1YmRpdmlzaW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zdWJkaXZpc2lvbikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHNlcXVlbmNlIHByb3h5IHdoaWNoIGNhbiBiZSBtb25pdG9yZWQgdG8gY3JlYXRlIHN1YnNlcXVlbmNlc1xuICAgICAqL1xuICAgIF9jcmVhdGVTZXF1ZW5jZShhcnJheSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGFycmF5LCB7XG4gICAgICAgICAgICBnZXQ6ICh0YXJnZXQsIHByb3BlcnR5KSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gcHJvcGVydHkgaXMgaW5kZXggaW4gdGhpcyBjYXNlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiAodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcocHJvcGVydHkpICYmIGlzRmluaXRlKHBhcnNlSW50KHByb3BlcnR5LCAxMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHRoaXMuX2NyZWF0ZVNlcXVlbmNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNVcGRhdGVkKCk7XG4gICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRydWUgdG8gYWNjZXB0IHRoZSBjaGFuZ2VzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgc2VxdWVuY2UgaGFzIGNoYW5nZWQsIGFsbCBvZiB0aGUgZXZlbnRzIG5lZWQgdG8gYmUgcmVjcmVhdGVkXG4gICAgICovXG4gICAgX2V2ZW50c1VwZGF0ZWQoKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZVNlcXVlbmNlKHRoaXMuX2V2ZW50c0FycmF5LCB0aGlzLl9zdWJkaXZpc2lvbiwgdGhpcy5zdGFydE9mZnNldCk7XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgbG9vcEVuZFxuICAgICAgICB0aGlzLmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJlc2NoZWR1bGUgYWxsIG9mIHRoZSBldmVudHMgdGhhdCBuZWVkIHRvIGJlIHJlc2NoZWR1bGVkXG4gICAgICovXG4gICAgX3Jlc2NoZWR1bGVTZXF1ZW5jZShzZXF1ZW5jZSwgc3ViZGl2aXNpb24sIHN0YXJ0T2Zmc2V0KSB7XG4gICAgICAgIHNlcXVlbmNlLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXZlbnRPZmZzZXQgPSBpbmRleCAqIChzdWJkaXZpc2lvbikgKyBzdGFydE9mZnNldDtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVTZXF1ZW5jZSh2YWx1ZSwgc3ViZGl2aXNpb24gLyB2YWx1ZS5sZW5ndGgsIGV2ZW50T2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgZXZlbnRPZmZzZXQsIFwiaVwiKS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0LmFkZChzdGFydFRpbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGltZSBvZiB0aGUgaW5kZXggZ2l2ZW4gdGhlIFNlcXVlbmNlJ3Mgc3ViZGl2aXNpb25cbiAgICAgKiBAcGFyYW0gIGluZGV4XG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGF0IGluZGV4XG4gICAgICovXG4gICAgX2luZGV4VGltZShpbmRleCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBpbmRleCAqICh0aGlzLl9zdWJkaXZpc2lvbikgKyB0aGlzLnN0YXJ0T2Zmc2V0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5fcGFydC5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJ0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFBST1hZIENBTExTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmxvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGwpIHtcbiAgICAgICAgdGhpcy5fcGFydC5sb29wID0gbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBzZXF1ZW5jZSBzaG91bGQgc3RhcnQgbG9vcGluZ1xuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gaW5kZXg7XG4gICAgICAgIHRoaXMuX3BhcnQubG9vcFN0YXJ0ID0gdGhpcy5faW5kZXhUaW1lKGluZGV4KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBzZXF1ZW5jZSBzaG91bGQgZW5kIGxvb3BpbmdcbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGluZGV4KSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0Lmxvb3BFbmQgPSB0aGlzLl9pbmRleFRpbWUodGhpcy5fZXZlbnRzQXJyYXkubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnQubG9vcEVuZCA9IHRoaXMuX2luZGV4VGltZShpbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHN0YXJ0T2Zmc2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KHN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX3BhcnQuc3RhcnRPZmZzZXQgPSBzdGFydDtcbiAgICB9XG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGFydC5wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgIH1cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnByb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9wYXJ0LnByb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wcm9ncmVzcztcbiAgICB9XG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9wYXJ0Lmh1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBldmVudHNcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5sZW5ndGg7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2VxdWVuY2UuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vTG9vcFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGFydFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGF0dGVyblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2VxdWVuY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdCwgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBHYWluVG9BdWRpbyB9IGZyb20gXCIuLi8uLi9zaWduYWwvR2FpblRvQXVkaW9cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG4vKipcbiAqIFRvbmUuQ3Jvc3NmYWRlIHByb3ZpZGVzIGVxdWFsIHBvd2VyIGZhZGluZyBiZXR3ZWVuIHR3byBpbnB1dHMuXG4gKiBNb3JlIG9uIGNyb3NzZmFkaW5nIHRlY2huaXF1ZSBbaGVyZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmFkZV8oYXVkaW9fZW5naW5lZXJpbmcpI0Nyb3NzZmFkaW5nKS5cbiAqIGBgYFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tK1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICs+IGlucHV0IGEgKz4tLStcbiAqICstLS0tLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAgICAgfCAgICAgICAgIHwgICB8XG4gKiB8IDFzIHNpZ25hbCArPi0tPiBzdGVyZW9QYW5uZXJOb2RlICBMICs+LS0tLT4gZ2FpbiAgICB8ICAgfFxuICogKy0tLS0tLS0tLS0tKyAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICArLS0tLS0tLS0tKyAgIHxcbiAqICAgICAgICAgICAgICAgKy0+IHBhbiAgICAgICAgICAgICAgIFIgKz4tKyAgICAgICAgICAgICAgICB8ICAgKy0tLS0tLS0tK1xuICogICAgICAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0rICB8ICAgICAgICAgICAgICAgICstLS0+IG91dHB1dCArPlxuICogICstLS0tLS0rICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICArLS0tLS0tLS0tKyAgIHwgICArLS0tLS0tLS0rXG4gKiAgfCBmYWRlICs+LS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKz4gaW5wdXQgYiArPi0tK1xuICogICstLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICB8ICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0+IGdhaW4gICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY3Jvc3NGYWRlID0gbmV3IFRvbmUuQ3Jvc3NGYWRlKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gY29ubmVjdCB0d28gaW5wdXRzIFRvbmUudG8gYS9iXG4gKiBjb25zdCBpbnB1dEEgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDQ0MCwgXCJzcXVhcmVcIikuY29ubmVjdChjcm9zc0ZhZGUuYSkuc3RhcnQoKTtcbiAqIGNvbnN0IGlucHV0QiA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNpbmVcIikuY29ubmVjdChjcm9zc0ZhZGUuYikuc3RhcnQoKTtcbiAqIC8vIHVzZSB0aGUgZmFkZSB0byBjb250cm9sIHRoZSBtaXggYmV0d2VlbiB0aGUgdHdvXG4gKiBjcm9zc0ZhZGUuZmFkZS52YWx1ZSA9IDAuNTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENyb3NzRmFkZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKENyb3NzRmFkZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZhZGVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ3Jvc3NGYWRlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3Jvc3NmYWRpbmcgaXMgZG9uZSBieSBhIFN0ZXJlb1Bhbm5lck5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNwbGl0IHRoZSBvdXRwdXQgb2YgdGhlIHBhbm5lciBub2RlIGludG8gdHdvIHZhbHVlcyB1c2VkIHRvIGNvbnRyb2wgdGhlIGdhaW5zLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3BsaXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKDIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydCB0aGUgZmFkZSB2YWx1ZSBpbnRvIGFuIGF1ZGlvIHJhbmdlIHZhbHVlIHNvIGl0IGNhbiBiZSBjb25uZWN0ZWRcbiAgICAgICAgICogdG8gdGhlIHBhbm5lci5wYW4gQXVkaW9QYXJhbVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZzJhID0gbmV3IEdhaW5Ub0F1ZGlvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHdoaWNoIGlzIGF0IGZ1bGwgbGV2ZWwgd2hlbiBmYWRlID0gMFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgd2hpY2ggaXMgYXQgZnVsbCBsZXZlbCB3aGVuIGZhZGUgPSAxXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmIgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgaXMgYSBtaXggYmV0d2VlbiBgYWAgYW5kIGBiYCBhdCB0aGUgcmF0aW8gb2YgYGZhZGVgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuYSwgdGhpcy5iXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENyb3NzRmFkZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZhZGVcIl0pO1xuICAgICAgICB0aGlzLmZhZGUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mYWRlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmYWRlXCIpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMSkuY29ubmVjdCh0aGlzLl9wYW5uZXIpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFxuICAgICAgICAvLyBkb2Vzbid0IG1ha2UgYW55IGRpZmZlcmVuY2UgZm9yIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9pc3N1ZXMvNjQ3XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zcGxpdCwgdGhpcy5hLmdhaW4sIDApO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NwbGl0LCB0aGlzLmIuZ2FpbiwgMSk7XG4gICAgICAgIHRoaXMuZmFkZS5jaGFpbih0aGlzLl9nMmEsIHRoaXMuX3Bhbm5lci5wYW4pO1xuICAgICAgICB0aGlzLmEuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuYi5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZhZGU6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5hLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5iLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZhZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nMmEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNyb3NzRmFkZS5qcy5tYXAiLCJpbXBvcnQgeyBDcm9zc0ZhZGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEVmZmVjdCBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgZWZmZWN0cy4gQ29ubmVjdCB0aGUgZWZmZWN0IGJldHdlZW5cbiAqIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm4gR2Fpbk5vZGVzLCB0aGVuIGNvbnRyb2wgdGhlIGFtb3VudCBvZlxuICogZWZmZWN0IHdoaWNoIGdvZXMgdG8gdGhlIG91dHB1dCB1c2luZyB0aGUgd2V0IGNvbnRyb2wuXG4gKi9cbmV4cG9ydCBjbGFzcyBFZmZlY3QgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVmZmVjdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGRyeXdldCBrbm9iIHRvIGNvbnRyb2wgdGhlIGFtb3VudCBvZiBlZmZlY3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2RyeVdldCA9IG5ldyBDcm9zc0ZhZGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgd2V0IGNvbnRyb2wgaXMgaG93IG11Y2ggb2YgdGhlIGVmZmVjdGVkXG4gICAgICAgICAqIHdpbGwgcGFzcyB0aHJvdWdoIHRvIHRoZSBvdXRwdXQuIDEgPSAxMDAlIGVmZmVjdGVkXG4gICAgICAgICAqIHNpZ25hbCwgMCA9IDEwMCUgZHJ5IHNpZ25hbC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBjb25uZWN0IHRoZSBlZmZlY3RTZW5kIHRvIHRoZSBpbnB1dCBvZiBodGUgZWZmZWN0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGUgZWZmZWN0IHRvIHRoZSBlZmZlY3RSZXR1cm5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZWZmZWN0IGlucHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlZmZlY3Qgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2RyeVdldDtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5mYW4odGhpcy5fZHJ5V2V0LmEsIHRoaXMuZWZmZWN0U2VuZCk7XG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmNvbm5lY3QodGhpcy5fZHJ5V2V0LmIpO1xuICAgICAgICB0aGlzLndldC5zZXRWYWx1ZUF0VGltZShvcHRpb25zLndldCwgMCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5lZmZlY3RSZXR1cm4sIHRoaXMuZWZmZWN0U2VuZF07XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwid2V0XCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2V0OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhaW5zIHRoZSBlZmZlY3QgaW4gYmV0d2VlbiB0aGUgZWZmZWN0U2VuZCBhbmQgZWZmZWN0UmV0dXJuXG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdChlZmZlY3QpIHtcbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBpbnRlcm5hbCBjaGFubmVsc1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzLnB1c2goZWZmZWN0KTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKGVmZmVjdCwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVmZmVjdFJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvRWZmZWN0XCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIExGTy1iYXNlZCBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgTEZPRWZmZWN0IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxGT0VmZmVjdFwiO1xuICAgICAgICB0aGlzLl9sZm8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBhbXBsaXR1ZGU6IG9wdGlvbnMuZGVwdGgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICBkZXB0aDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBlZmZlY3QuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm8uc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBsZm9cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBmaWx0ZXIgdG8gdGhlIHRyYW5zcG9ydC4gU2VlIFtbTEZPLnN5bmNdXVxuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmby5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm8udW5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgTEZPJ3Mgb3NjaWxsYXRvcjogU2VlIFtbT3NjaWxsYXRvci50eXBlXV1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLnN0YXJ0KCkuY29ubmVjdChhdXRvRmlsdGVyKTtcbiAgICAgKiBhdXRvRmlsdGVyLnR5cGUgPSBcInNxdWFyZVwiO1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXB0aC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxGT0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPRWZmZWN0IH0gZnJvbSBcIi4vTEZPRWZmZWN0XCI7XG4vKipcbiAqIEF1dG9GaWx0ZXIgaXMgYSBUb25lLkZpbHRlciB3aXRoIGEgVG9uZS5MRk8gY29ubmVjdGVkIHRvIHRoZSBmaWx0ZXIgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAqIFNldHRpbmcgdGhlIExGTyByYXRlIGFuZCBkZXB0aCBhbGxvd3MgZm9yIGNvbnRyb2wgb3ZlciB0aGUgZmlsdGVyIG1vZHVsYXRpb24gcmF0ZVxuICogYW5kIGRlcHRoLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYW4gYXV0b2ZpbHRlciBhbmQgc3RhcnQgaXQncyBMRk9cbiAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKFwiNG5cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIGZpbHRlciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhdXRvRmlsdGVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b0ZpbHRlciBleHRlbmRzIExGT0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9GaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9GaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9GaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiXSk7XG4gICAgICAgIHRoaXMuZmlsdGVyID0gbmV3IEZpbHRlcihPYmplY3QuYXNzaWduKG9wdGlvbnMuZmlsdGVyLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pKTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuZmlsdGVyKTtcbiAgICAgICAgdGhpcy5fbGZvLmNvbm5lY3QodGhpcy5maWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLmJhc2VGcmVxdWVuY3kgPSBvcHRpb25zLmJhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTEZPRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDIuNixcbiAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIGZpbHRlcidzIGN1dG9mZiBmcmVxdWVuY3kuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8ubWluO1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHRoaXMuX2xmby5taW4gPSB0aGlzLnRvRnJlcXVlbmN5KGZyZXEpO1xuICAgICAgICAvLyBhbmQgc2V0IHRoZSBtYXhcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIGZpbHRlcidzIGN1dG9mZiBmcmVxdWVuY3kuXG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3QpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdDtcbiAgICAgICAgdGhpcy5fbGZvLm1heCA9IHRoaXMuX2xmby5taW4gKiBNYXRoLnBvdygyLCBvY3QpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b0ZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQYW5uZXIgaXMgYW4gZXF1YWwgcG93ZXIgTGVmdC9SaWdodCBQYW5uZXIuIEl0IGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIFN0ZXJlb1Bhbm5lck5vZGUuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiAvLyBtb3ZlIHRoZSBpbnB1dCBzaWduYWwgZnJvbSByaWdodCB0byBsZWZ0XG4gKiBcdGNvbnN0IHBhbm5lciA9IG5ldyBUb25lLlBhbm5lcigxKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdHBhbm5lci5wYW4ucmFtcFRvKC0xLCAwLjUpO1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDEwMCkuY29ubmVjdChwYW5uZXIpLnN0YXJ0KCk7XG4gKiB9LCAwLjUsIDIpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFubmVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhbm5lclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHBhbm5lciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9wYW5uZXI7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fcGFubmVyO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCJdKTtcbiAgICAgICAgdGhpcy5wYW4gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wYW4sXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICBtaW5WYWx1ZTogLTEsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFxuICAgICAgICAvLyBkb2Vzbid0IG1ha2UgYW55IGRpZmZlcmVuY2UgZm9yIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9pc3N1ZXMvNjQ3XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnQgPSBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudE1vZGUgPSBcImV4cGxpY2l0XCI7XG4gICAgICAgIC8vIGluaXRpYWwgdmFsdWVcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJwYW5cIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwYW46IDAsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFubmVyLmpzLm1hcCIsImltcG9ydCB7IFBhbm5lciB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9QYW5uZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPRWZmZWN0IH0gZnJvbSBcIi4vTEZPRWZmZWN0XCI7XG4vKipcbiAqIEF1dG9QYW5uZXIgaXMgYSBbW1Bhbm5lcl1dIHdpdGggYW4gW1tMRk9dXSBjb25uZWN0ZWQgdG8gdGhlIHBhbiBhbW91bnQuXG4gKiBbUmVsYXRlZCBSZWFkaW5nXShodHRwczovL3d3dy5hYmxldG9uLmNvbS9lbi9ibG9nL2F1dG9wYW4tY2hvcHBlci1lZmZlY3QtYW5kLW1vcmUtbGl2ZXNjaG9vbC8pLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYW4gYXV0b3Bhbm5lciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IGF1dG9QYW5uZXIgPSBuZXcgVG9uZS5BdXRvUGFubmVyKFwiNG5cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIHBhbm5lciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhdXRvUGFubmVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b1Bhbm5lciBleHRlbmRzIExGT0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9QYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdXRvUGFubmVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gbmV3IFBhbm5lcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fcGFubmVyKTtcbiAgICAgICAgdGhpcy5fbGZvLmNvbm5lY3QodGhpcy5fcGFubmVyLnBhbik7XG4gICAgICAgIHRoaXMuX2xmby5taW4gPSAtMTtcbiAgICAgICAgdGhpcy5fbGZvLm1heCA9IDE7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTEZPRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvUGFubmVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lUG9sZUZpbHRlciB9IGZyb20gXCIuLi9maWx0ZXIvT25lUG9sZUZpbHRlclwiO1xuaW1wb3J0IHsgQWJzIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BYnNcIjtcbi8qKlxuICogRm9sbG93ZXIgaXMgYSBzaW1wbGUgZW52ZWxvcGUgZm9sbG93ZXIuXG4gKiBJdCdzIGltcGxlbWVudGVkIGJ5IGFwcGx5aW5nIGEgbG93cGFzcyBmaWx0ZXIgdG8gdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBgYGBcbiAqICAgICAgICAgICstLS0tLSsgICAgKy0tLS0tLS0tLS0tLS0tLStcbiAqIElucHV0ICstLT4gQWJzICstLS0tPiBPbmVQb2xlRmlsdGVyICstLT4gT3V0cHV0XG4gKiAgICAgICAgICArLS0tLS0rICAgICstLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZvbGxvd2VyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZvbGxvd2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRm9sbG93ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZvbGxvd2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fYWJzID0gdGhpcy5pbnB1dCA9IG5ldyBBYnMoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MgPSB0aGlzLm91dHB1dCA9IG5ldyBPbmVQb2xlRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSAvIHRoaXMudG9TZWNvbmRzKG9wdGlvbnMuc21vb3RoaW5nKSxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hYnMuY29ubmVjdCh0aGlzLl9sb3dwYXNzKTtcbiAgICAgICAgdGhpcy5fc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuMDVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyBhIHZhbHVlIGNoYW5nZSB0byBhcnJpdmUgYXQgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Ntb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyhzbW9vdGhpbmcpIHtcbiAgICAgICAgdGhpcy5fc21vb3RoaW5nID0gc21vb3RoaW5nO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSA9IDEgLyB0aGlzLnRvU2Vjb25kcyh0aGlzLnNtb290aGluZyk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZvbGxvd2VyLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBGb2xsb3dlciB9IGZyb20gXCIuLi9jb21wb25lbnQvYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgU2NhbGVFeHAgfSBmcm9tIFwiLi4vc2lnbmFsL1NjYWxlRXhwXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEF1dG9XYWggY29ubmVjdHMgYSBbW0ZvbGxvd2VyXV0gdG8gYSBbW0ZpbHRlcl1dLlxuICogVGhlIGZyZXF1ZW5jeSBvZiB0aGUgZmlsdGVyLCBmb2xsb3dzIHRoZSBpbnB1dCBhbXBsaXR1ZGUgY3VydmUuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGF1dG9XYWggPSBuZXcgVG9uZS5BdXRvV2FoKDUwLCA2LCAtMzApLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGluaXRpYWxpemUgdGhlIHN5bnRoIGFuZCBjb25uZWN0IHRvIGF1dG93YWhcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KGF1dG9XYWgpO1xuICogLy8gUSB2YWx1ZSBpbmZsdWVuY2VzIHRoZSBlZmZlY3Qgb2YgdGhlIHdhaCAtIGRlZmF1bHQgaXMgMlxuICogYXV0b1dhaC5RLnZhbHVlID0gNjtcbiAqIC8vIG1vcmUgYXVkaWJsZSBvbiBoaWdoZXIgbm90ZXNcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9XYWggZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvV2FoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYmFzZUZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJzZW5zaXRpdml0eVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9XYWhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9XYWguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcInNlbnNpdGl2aXR5XCJdKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBuZXcgRm9sbG93ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiBvcHRpb25zLmZvbGxvd2VyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZSA9IG5ldyBTY2FsZUV4cCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBleHBvbmVudDogMC41LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5faW5wdXRCb29zdCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9iYW5kcGFzcyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcm9sbG9mZjogLTQ4LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgUTogb3B0aW9ucy5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGVha2luZyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJwZWFraW5nXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcuZ2Fpbi52YWx1ZSA9IG9wdGlvbnMuZ2FpbjtcbiAgICAgICAgdGhpcy5nYWluID0gdGhpcy5fcGVha2luZy5nYWluO1xuICAgICAgICB0aGlzLlEgPSB0aGlzLl9iYW5kcGFzcy5RO1xuICAgICAgICAvLyB0aGUgY29udHJvbCBzaWduYWwgcGF0aFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5faW5wdXRCb29zdCwgdGhpcy5fZm9sbG93ZXIsIHRoaXMuX3N3ZWVwUmFuZ2UpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmNvbm5lY3QodGhpcy5fYmFuZHBhc3MuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5jb25uZWN0KHRoaXMuX3BlYWtpbmcuZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gdGhlIGZpbHRlcmVkIHBhdGhcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2JhbmRwYXNzLCB0aGlzLl9wZWFraW5nLCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgICAgIHRoaXMuc2Vuc2l0aXZpdHkgPSBvcHRpb25zLnNlbnNpdGl2aXR5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDEwMCxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDYsXG4gICAgICAgICAgICBzZW5zaXRpdml0eTogMCxcbiAgICAgICAgICAgIFE6IDIsXG4gICAgICAgICAgICBnYWluOiAyLFxuICAgICAgICAgICAgZm9sbG93ZXI6IDAuMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyB0aGF0IHRoZSBmaWx0ZXIgd2lsbCBzd2VlcCBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZvbGxvd2VyJ3Mgc21vb3RoaW5nIHRpbWVcbiAgICAgKi9cbiAgICBnZXQgZm9sbG93ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBmb2xsb3dlcihmb2xsb3dlcikge1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmcgPSBmb2xsb3dlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgZnJlcXVlbmN5IGZyb20gd2hpY2ggdGhlIHN3ZWVwIHdpbGwgc3RhcnQgZnJvbS5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGJhc2VGcmVxKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KGJhc2VGcmVxKTtcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2Vuc2l0aXZpdHkgdG8gY29udHJvbCBob3cgcmVzcG9uc2l2ZSB0byB0aGUgaW5wdXQgc2lnbmFsIHRoZSBmaWx0ZXIgaXMuXG4gICAgICovXG4gICAgZ2V0IHNlbnNpdGl2aXR5KCkge1xuICAgICAgICByZXR1cm4gZ2FpblRvRGIoMSAvIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSk7XG4gICAgfVxuICAgIHNldCBzZW5zaXRpdml0eShzZW5zaXRpdml0eSkge1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0LmdhaW4udmFsdWUgPSAxIC8gZGJUb0dhaW4oc2Vuc2l0aXZpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXRzIHRoZSBzd2VlcCByYW5nZSBvZiB0aGUgc2NhbGVyXG4gICAgICovXG4gICAgX3NldFN3ZWVwUmFuZ2UoKSB7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5tYXggPSBNYXRoLm1pbih0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgdGhpcy5fb2N0YXZlcyksIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMik7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYmFuZHBhc3MuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wZWFraW5nLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5faW5wdXRCb29zdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9XYWguanMubWFwIiwiaW1wb3J0IFwiLi4vY29yZS93b3JrbGV0L1NpbmdsZUlPUHJvY2Vzc29yLndvcmtsZXRcIjtcbmltcG9ydCB7IHJlZ2lzdGVyUHJvY2Vzc29yIH0gZnJvbSBcIi4uL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCB3b3JrbGV0TmFtZSA9IFwiYml0LWNydXNoZXJcIjtcbmV4cG9ydCBjb25zdCBiaXRDcnVzaGVyV29ya2xldCA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHRjbGFzcyBCaXRDcnVzaGVyV29ya2xldCBleHRlbmRzIFNpbmdsZUlPUHJvY2Vzc29yIHtcblxuXHRcdHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7XG5cdFx0XHRyZXR1cm4gW3tcblx0XHRcdFx0bmFtZTogXCJiaXRzXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMTIsXG5cdFx0XHRcdG1pblZhbHVlOiAxLFxuXHRcdFx0XHRtYXhWYWx1ZTogMTYsXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiAnay1yYXRlJ1xuXHRcdFx0fV07XG5cdFx0fVxuXG5cdFx0Z2VuZXJhdGUoaW5wdXQsIF9jaGFubmVsLCBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRjb25zdCBzdGVwID0gTWF0aC5wb3coMC41LCBwYXJhbWV0ZXJzLmJpdHMgLSAxKTtcblx0XHRcdGNvbnN0IHZhbCA9IHN0ZXAgKiBNYXRoLmZsb29yKGlucHV0IC8gc3RlcCArIDAuNSk7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0fVxuYDtcbnJlZ2lzdGVyUHJvY2Vzc29yKHdvcmtsZXROYW1lLCBiaXRDcnVzaGVyV29ya2xldCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CaXRDcnVzaGVyLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvV29ya2xldCB9IGZyb20gXCIuLi9jb3JlL3dvcmtsZXQvVG9uZUF1ZGlvV29ya2xldFwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgd29ya2xldE5hbWUgfSBmcm9tIFwiLi9CaXRDcnVzaGVyLndvcmtsZXRcIjtcbi8qKlxuICogQml0Q3J1c2hlciBkb3duLXNhbXBsZXMgdGhlIGluY29taW5nIHNpZ25hbCB0byBhIGRpZmZlcmVudCBiaXQgZGVwdGguXG4gKiBMb3dlcmluZyB0aGUgYml0IGRlcHRoIG9mIHRoZSBzaWduYWwgY3JlYXRlcyBkaXN0b3J0aW9uLiBSZWFkIG1vcmUgYWJvdXQgQml0Q3J1c2hpbmdcbiAqIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JpdGNydXNoZXIpLlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemUgY3J1c2hlciBhbmQgcm91dGUgYSBzeW50aCB0aHJvdWdoIGl0XG4gKiBjb25zdCBjcnVzaGVyID0gbmV3IFRvbmUuQml0Q3J1c2hlcig0KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChjcnVzaGVyKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgMik7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQml0Q3J1c2hlciBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQml0Q3J1c2hlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJpdHNcIl0pO1xuICAgICAgICB0aGlzLl9iaXRDcnVzaGVyV29ya2xldCA9IG5ldyBCaXRDcnVzaGVyV29ya2xldCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBiaXRzOiBvcHRpb25zLmJpdHMsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9iaXRDcnVzaGVyV29ya2xldCk7XG4gICAgICAgIHRoaXMuYml0cyA9IHRoaXMuX2JpdENydXNoZXJXb3JrbGV0LmJpdHM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJpdHM6IDQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2JpdENydXNoZXJXb3JrbGV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBJbnRlcm5hbCBjbGFzcyB3aGljaCBjcmVhdGVzIGFuIEF1ZGlvV29ya2xldCB0byBkbyB0aGUgYml0IGNydXNoaW5nXG4gKi9cbmNsYXNzIEJpdENydXNoZXJXb3JrbGV0IGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXJXb3JrbGV0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkJpdENydXNoZXJXb3JrbGV0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyV29ya2xldC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuYml0cyA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5iaXRzLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIG1pblZhbHVlOiAxLFxuICAgICAgICAgICAgbWF4VmFsdWU6IDE2LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb1dvcmtsZXQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYml0czogMTIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYXVkaW9Xb3JrbGV0TmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtsZXROYW1lO1xuICAgIH1cbiAgICBvblJlYWR5KG5vZGUpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCBub2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbnN0IGJpdHMgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiYml0c1wiKTtcbiAgICAgICAgdGhpcy5iaXRzLnNldFBhcmFtKGJpdHMpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYml0cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpdENydXNoZXIuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbi8qKlxuICogQ2hlYnlzaGV2IGlzIGEgd2F2ZXNoYXBlciB3aGljaCBpcyBnb29kXG4gKiBmb3IgbWFraW5nIGRpZmZlcmVudCB0eXBlcyBvZiBkaXN0b3J0aW9uIHNvdW5kcy5cbiAqIE5vdGUgdGhhdCBvZGQgb3JkZXJzIHNvdW5kIHZlcnkgZGlmZmVyZW50IGZyb20gZXZlbiBvbmVzLFxuICogYW5kIG9yZGVyID0gMSBpcyBubyBjaGFuZ2UuXG4gKiBSZWFkIG1vcmUgYXQgW211c2ljLmNvbHVtYmlhLmVkdV0oaHR0cDovL211c2ljLmNvbHVtYmlhLmVkdS9jbWMvbXVzaWNhbmRjb21wdXRlcnMvY2hhcHRlcjQvMDRfMDYucGhwKS5cbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYSBuZXcgY2hlYnlcbiAqIGNvbnN0IGNoZWJ5ID0gbmV3IFRvbmUuQ2hlYnlzaGV2KDUwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBjcmVhdGUgYSBtb25vc3ludGggY29ubmVjdGVkIHRvIG91ciBjaGVieVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Nb25vU3ludGgoKS5jb25uZWN0KGNoZWJ5KTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgMC40KTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIENoZWJ5c2hldiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENoZWJ5c2hldi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9yZGVyXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hlYnlzaGV2XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGVieXNoZXYuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvcmRlclwiXSk7XG4gICAgICAgIHRoaXMuX3NoYXBlciA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogNDA5NlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fb3JkZXIgPSBvcHRpb25zLm9yZGVyO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcbiAgICAgICAgdGhpcy5vcmRlciA9IG9wdGlvbnMub3JkZXI7XG4gICAgICAgIHRoaXMub3ZlcnNhbXBsZSA9IG9wdGlvbnMub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgb3JkZXI6IDEsXG4gICAgICAgICAgICBvdmVyc2FtcGxlOiBcIm5vbmVcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBjb2VmZmljaWVudCBmb3IgdGhhdCBkZWdyZWVcbiAgICAgKiBAcGFyYW0gIHggdGhlIHggdmFsdWVcbiAgICAgKiBAcGFyYW0gIGRlZ3JlZVxuICAgICAqIEBwYXJhbSAgbWVtbyBtZW1vaXplIHRoZSBjb21wdXRlZCB2YWx1ZS4gdGhpcyBzcGVlZHMgdXAgY29tcHV0YXRpb24gZ3JlYXRseS5cbiAgICAgKi9cbiAgICBfZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlLCBtZW1vKSB7XG4gICAgICAgIGlmIChtZW1vLmhhcyhkZWdyZWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbWVtby5nZXQoZGVncmVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWdyZWUgPT09IDApIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGVncmVlID09PSAxKSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIHgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCAyICogeCAqIHRoaXMuX2dldENvZWZmaWNpZW50KHgsIGRlZ3JlZSAtIDEsIG1lbW8pIC0gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMiwgbWVtbykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZW1vLmdldChkZWdyZWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3JkZXIgb2YgdGhlIENoZWJ5c2hldiBwb2x5bm9taWFsIHdoaWNoIGNyZWF0ZXMgdGhlIGVxdWF0aW9uIHdoaWNoIGlzIGFwcGxpZWQgdG8gdGhlIGluY29taW5nXG4gICAgICogc2lnbmFsIHRocm91Z2ggYSBUb25lLldhdmVTaGFwZXIuIFRoZSBlcXVhdGlvbnMgYXJlIGluIHRoZSBmb3JtOlxuICAgICAqIGBgYFxuICAgICAqIG9yZGVyIDI6IDJ4XjIgKyAxXG4gICAgICogb3JkZXIgMzogNHheMyArIDN4XG4gICAgICogYGBgXG4gICAgICogQG1pbiAxXG4gICAgICogQG1heCAxMDBcbiAgICAgKi9cbiAgICBnZXQgb3JkZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcmRlcjtcbiAgICB9XG4gICAgc2V0IG9yZGVyKG9yZGVyKSB7XG4gICAgICAgIHRoaXMuX29yZGVyID0gb3JkZXI7XG4gICAgICAgIHRoaXMuX3NoYXBlci5zZXRNYXAoKHggPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldENvZWZmaWNpZW50KHgsIG9yZGVyLCBuZXcgTWFwKCkpO1xuICAgICAgICB9KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2hlYnlzaGV2LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBTcGxpdCBzcGxpdHMgYW4gaW5jb21pbmcgc2lnbmFsIGludG8gdGhlIG51bWJlciBvZiBnaXZlbiBjaGFubmVscy5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3BsaXQgPSBuZXcgVG9uZS5TcGxpdCgpO1xuICogLy8gc3RlcmVvU2lnbmFsLmNvbm5lY3Qoc3BsaXQpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgU3BsaXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNwbGl0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG9wdGlvbnMuY2hhbm5lbHMpO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX3NwbGl0dGVyXTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBNZXJnZSBicmluZ3MgbXVsdGlwbGUgbW9ubyBpbnB1dCBjaGFubmVscyBpbnRvIGEgc2luZ2xlIG11bHRpY2hhbm5lbCBvdXRwdXQgY2hhbm5lbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWVyZ2UgPSBuZXcgVG9uZS5NZXJnZSgpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHJvdXRpbmcgYSBzaW5lIHRvbmUgaW4gdGhlIGxlZnQgY2hhbm5lbFxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobWVyZ2UsIDAsIDApLnN0YXJ0KCk7XG4gKiAvLyBhbmQgbm9pc2UgaW4gdGhlIHJpZ2h0IGNoYW5uZWxcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5jb25uZWN0KG1lcmdlLCAwLCAxKS5zdGFydCgpOztcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1lcmdlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1lcmdlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXJnZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSk7XG4gICAgICAgIHRoaXMuX21lcmdlciA9IHRoaXMub3V0cHV0ID0gdGhpcy5pbnB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsTWVyZ2VyKG9wdGlvbnMuY2hhbm5lbHMpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1lcmdlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QsIGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NZXJnZVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBTdGVyZW8gZWZmZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb0VmZmVjdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3RlcmVvRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gZm9yY2UgbW9ubyBzb3VyY2VzIHRvIGJlIHN0ZXJlb1xuICAgICAgICB0aGlzLmlucHV0LmNoYW5uZWxDb3VudCA9IDI7XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgdGhpcy5fZHJ5V2V0ID0gdGhpcy5vdXRwdXQgPSBuZXcgQ3Jvc3NGYWRlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGU6IG9wdGlvbnMud2V0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLndldCA9IHRoaXMuX2RyeVdldC5mYWRlO1xuICAgICAgICB0aGlzLl9zcGxpdCA9IG5ldyBTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gZHJ5IHdldCBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZHJ5V2V0LmEpO1xuICAgICAgICB0aGlzLl9tZXJnZS5jb25uZWN0KHRoaXMuX2RyeVdldC5iKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wid2V0XCJdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgbGVmdCBwYXJ0IG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0TGVmdCguLi5ub2Rlcykge1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KG5vZGVzWzBdLCAwLCAwKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyguLi5ub2Rlcyk7XG4gICAgICAgIGNvbm5lY3Qobm9kZXNbbm9kZXMubGVuZ3RoIC0gMV0sIHRoaXMuX21lcmdlLCAwLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgcmlnaHQgcGFydCBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdFJpZ2h0KC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3Qobm9kZXNbMF0sIDEsIDApO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKTtcbiAgICAgICAgY29ubmVjdChub2Rlc1tub2Rlcy5sZW5ndGggLSAxXSwgdGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2V0OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NZXJnZVwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBzdGVyZW8gZmVlZGJhY2sgZWZmZWN0cyB3aGVyZSB0aGUgZWZmZWN0UmV0dXJuIGlzIGZlZCBiYWNrIGludG8gdGhlIHNhbWUgY2hhbm5lbC5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mZWVkYmFjayxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdCA9IG5ldyBTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZS5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrU3BsaXQpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja01lcmdlLmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyB0aGUgbGVmdCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSBsZWZ0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQuY29ubmVjdCh0aGlzLl9mZWVkYmFja0wsIDAsIDApO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAwKTtcbiAgICAgICAgLy8gdGhlIHJpZ2h0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQuY29ubmVjdCh0aGlzLl9mZWVkYmFja1IsIDEsIDApO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAxKTtcbiAgICAgICAgLy8gdGhlIGZlZWRiYWNrIGNvbnRyb2xcbiAgICAgICAgdGhpcy5mZWVkYmFjay5mYW4odGhpcy5fZmVlZGJhY2tMLmdhaW4sIHRoaXMuX2ZlZWRiYWNrUi5nYWluKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZmVlZGJhY2tcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmZWVkYmFjazogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9GZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9GZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvU3RlcmVvRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENob3J1cyBpcyBhIHN0ZXJlbyBjaG9ydXMgZWZmZWN0IGNvbXBvc2VkIG9mIGEgbGVmdCBhbmQgcmlnaHQgZGVsYXkgd2l0aCBhbiBbW0xGT11dIGFwcGxpZWQgdG8gdGhlIGRlbGF5VGltZSBvZiBlYWNoIGNoYW5uZWwuXG4gKiBXaGVuIFtbZmVlZGJhY2tdXSBpcyBzZXQgdG8gYSB2YWx1ZSBsYXJnZXIgdGhhbiAwLCB5b3UgYWxzbyBnZXQgRmxhbmdlci10eXBlIGVmZmVjdHMuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYS9ibG9iL21hc3Rlci90dW5hLmpzKS5cbiAqIFJlYWQgbW9yZSBvbiB0aGUgY2hvcnVzIGVmZmVjdCBvbiBbU291bmRPblNvdW5kXShodHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL2p1bjA0L2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjaG9ydXMgPSBuZXcgVG9uZS5DaG9ydXMoNCwgMi41LCAwLjUpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS5jb25uZWN0KGNob3J1cyk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDM1wiLCBcIkUzXCIsIFwiRzNcIl0sIFwiOG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQ2hvcnVzIGV4dGVuZHMgU3RlcmVvRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaG9ydXMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZWxheVRpbWVcIiwgXCJkZXB0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNob3J1c1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hvcnVzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVsYXlUaW1lXCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9kZXB0aCA9IG9wdGlvbnMuZGVwdGg7XG4gICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IG9wdGlvbnMuZGVsYXlUaW1lIC8gMTAwMDtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBwaGFzZTogMTgwXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVMID0gbmV3IERlbGF5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVSID0gbmV3IERlbGF5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmb0wuZnJlcXVlbmN5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICAvLyBoYXZlIG9uZSBMRk8gZnJlcXVlbmN5IGNvbnRyb2wgdGhlIG90aGVyXG4gICAgICAgIHRoaXMuX2xmb0wuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KHRoaXMuX2RlbGF5Tm9kZUwpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9kZWxheU5vZGVSKTtcbiAgICAgICAgLy8gbGZvIHNldHVwXG4gICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9kZWxheU5vZGVMLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1IuY29ubmVjdCh0aGlzLl9kZWxheU5vZGVSLmRlbGF5VGltZSk7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZXNcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2RlcHRoO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLjUsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDMuNSxcbiAgICAgICAgICAgIGRlcHRoOiAwLjcsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIHNwcmVhZDogMTgwLFxuICAgICAgICAgICAgZmVlZGJhY2s6IDAsXG4gICAgICAgICAgICB3ZXQ6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZXB0aCBvZiB0aGUgZWZmZWN0LiBBIGRlcHRoIG9mIDEgbWFrZXMgdGhlIGRlbGF5VGltZVxuICAgICAqIG1vZHVsYXRlIGJldHdlZW4gMCBhbmQgMipkZWxheVRpbWUgKGNlbnRlcmVkIGFyb3VuZCB0aGUgZGVsYXlUaW1lKS5cbiAgICAgKi9cbiAgICBnZXQgZGVwdGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXB0aDtcbiAgICB9XG4gICAgc2V0IGRlcHRoKGRlcHRoKSB7XG4gICAgICAgIHRoaXMuX2RlcHRoID0gZGVwdGg7XG4gICAgICAgIGNvbnN0IGRldmlhdGlvbiA9IHRoaXMuX2RlbGF5VGltZSAqIGRlcHRoO1xuICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG4gICAgICAgIHRoaXMuX2xmb0wubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuICAgICAgICB0aGlzLl9sZm9SLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG4gICAgICAgIHRoaXMuX2xmb1IubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVsYXlUaW1lIGluIG1pbGxpc2Vjb25kcyBvZiB0aGUgY2hvcnVzLiBBIGxhcmdlciBkZWxheVRpbWVcbiAgICAgKiB3aWxsIGdpdmUgYSBtb3JlIHByb25vdW5jZWQgZWZmZWN0LiBOb21pbmFsIHJhbmdlIGEgZGVsYXlUaW1lXG4gICAgICogaXMgYmV0d2VlbiAyIGFuZCAyMG1zLlxuICAgICAqL1xuICAgIGdldCBkZWxheVRpbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWUgKiAxMDAwO1xuICAgIH1cbiAgICBzZXQgZGVsYXlUaW1lKGRlbGF5VGltZSkge1xuICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBkZWxheVRpbWUgLyAxMDAwO1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fZGVwdGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yIHR5cGUgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb0wudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9sZm9SLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbW91bnQgb2Ygc3RlcmVvIHNwcmVhZC4gV2hlbiBzZXQgdG8gMCwgYm90aCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBjZW50cmFsbHkuXG4gICAgICogV2hlbiBzZXQgdG8gMTgwLCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBoYXJkIGxlZnQgYW5kIHJpZ2h0IHJlc3BlY3RpdmVseS5cbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvUi5waGFzZSAtIHRoaXMuX2xmb0wucGhhc2U7XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX2xmb0wucGhhc2UgPSA5MCAtIChzcHJlYWQgLyAyKTtcbiAgICAgICAgdGhpcy5fbGZvUi5waGFzZSA9IChzcHJlYWQgLyAyKSArIDkwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZWZmZWN0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxmb1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGZpbHRlciB0byB0aGUgdHJhbnNwb3J0LiBTZWUgW1tMRk8uc3luY11dXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi51bnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVMLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2hvcnVzLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG4vKipcbiAqIEEgc2ltcGxlIGRpc3RvcnRpb24gZWZmZWN0IHVzaW5nIFRvbmUuV2F2ZVNoYXBlci5cbiAqIEFsZ29yaXRobSBmcm9tIFt0aGlzIHN0YWNrb3ZlcmZsb3cgYW5zd2VyXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjMxMzQwOCkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGRpc3QgPSBuZXcgVG9uZS5EaXN0b3J0aW9uKDAuOCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZm0gPSBuZXcgVG9uZS5GTVN5bnRoKCkuY29ubmVjdChkaXN0KTtcbiAqIGZtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTFcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIERpc3RvcnRpb24gZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEaXN0b3J0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGlzdG9ydGlvblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRpc3RvcnRpb25cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERpc3RvcnRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkaXN0b3J0aW9uXCJdKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiA0MDk2LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZGlzdG9ydGlvbiA9IG9wdGlvbnMuZGlzdG9ydGlvbjtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX3NoYXBlcik7XG4gICAgICAgIHRoaXMuZGlzdG9ydGlvbiA9IG9wdGlvbnMuZGlzdG9ydGlvbjtcbiAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkaXN0b3J0aW9uOiAwLjQsXG4gICAgICAgICAgICBvdmVyc2FtcGxlOiBcIm5vbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgZGlzdG9ydGlvbi4gTm9taW5hbCByYW5nZSBpcyBiZXR3ZWVuIDAgYW5kIDEuXG4gICAgICovXG4gICAgZ2V0IGRpc3RvcnRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXN0b3J0aW9uO1xuICAgIH1cbiAgICBzZXQgZGlzdG9ydGlvbihhbW91bnQpIHtcbiAgICAgICAgdGhpcy5fZGlzdG9ydGlvbiA9IGFtb3VudDtcbiAgICAgICAgY29uc3QgayA9IGFtb3VudCAqIDEwMDtcbiAgICAgICAgY29uc3QgZGVnID0gTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgdGhpcy5fc2hhcGVyLnNldE1hcCgoeCkgPT4ge1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHgpIDwgMC4wMDEpIHtcbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgb3V0cHV0IDAgd2hlbiBpbnB1dCBpcyAwXG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKDMgKyBrKSAqIHggKiAyMCAqIGRlZyAvIChNYXRoLlBJICsgayAqIE1hdGguYWJzKHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGlzdG9ydGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbi8qKlxuICogRmVlZGJhY2tFZmZlY3QgcHJvdmlkZXMgYSBsb29wIGJldHdlZW4gYW4gYXVkaW8gc291cmNlIGFuZCBpdHMgb3duIG91dHB1dC5cbiAqIFRoaXMgaXMgYSBiYXNlLWNsYXNzIGZvciBmZWVkYmFjayBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmVlZGJhY2tFZmZlY3RcIjtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5mZWVkYmFjayxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZlZWRiYWNrID0gdGhpcy5fZmVlZGJhY2tHYWluLmdhaW47XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZmVlZGJhY2tcIik7XG4gICAgICAgIC8vIHRoZSBmZWVkYmFjayBsb29wXG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmNoYWluKHRoaXMuX2ZlZWRiYWNrR2FpbiwgdGhpcy5lZmZlY3RTZW5kKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmVlZGJhY2s6IDAuMTI1LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tFZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vRmVlZGJhY2tFZmZlY3RcIjtcbi8qKlxuICogRmVlZGJhY2tEZWxheSBpcyBhIERlbGF5Tm9kZSBpbiB3aGljaCBwYXJ0IG9mIG91dHB1dCBzaWduYWwgaXMgZmVkIGJhY2sgaW50byB0aGUgZGVsYXkuXG4gKlxuICogQHBhcmFtIGRlbGF5VGltZSBUaGUgZGVsYXkgYXBwbGllZCB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogQHBhcmFtIGZlZWRiYWNrIFRoZSBhbW91bnQgb2YgdGhlIGVmZmVjdGVkIHNpZ25hbCB3aGljaCBpcyBmZWQgYmFjayB0aHJvdWdoIHRoZSBkZWxheS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmZWVkYmFja0RlbGF5ID0gbmV3IFRvbmUuRmVlZGJhY2tEZWxheShcIjhuXCIsIDAuNSkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgdG9tID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCh7XG4gKiBcdG9jdGF2ZXM6IDQsXG4gKiBcdHBpdGNoRGVjYXk6IDAuMVxuICogfSkuY29ubmVjdChmZWVkYmFja0RlbGF5KTtcbiAqIHRvbS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkEyXCIsIFwiMzJuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tEZWxheSBleHRlbmRzIEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmVlZGJhY2tEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZTtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fZGVsYXlOb2RlKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjI1LFxuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tEZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIFBoYXNlU2hpZnRBbGxwYXNzIGlzIGFuIHZlcnkgZWZmaWNpZW50IGltcGxlbWVudGF0aW9uIG9mIGEgSGlsYmVydCBUcmFuc2Zvcm1cbiAqIHVzaW5nIHR3byBBbGxwYXNzIGZpbHRlciBiYW5rcyB3aG9zZSBvdXRwdXRzIGhhdmUgYSBwaGFzZSBkaWZmZXJlbmNlIG9mIDkwwrAuXG4gKiBIZXJlIHRoZSBgb2Zmc2V0OTBgIHBoYXNlIGlzIG9mZnNldCBieSArOTDCsCBpbiByZWxhdGlvbiB0byBgb3V0cHV0YC5cbiAqIENvZWZmaWNpZW50cyBhbmQgc3RydWN0dXJlIHdhcyBkZXZlbG9wZWQgYnkgT2xsaSBOaWVtaXRhbG8uXG4gKiBGb3IgbW9yZSBkZXRhaWxzIHNlZTogaHR0cDovL3llaGFyLmNvbS9ibG9nLz9wPTM2OFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGhhc2VTaGlmdEFsbHBhc3MgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBoYXNlU2hpZnRBbGxwYXNzXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwaGFzZSBzaGlmdGVkIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBQaGFzZVNoaWZ0ZWQgYWxscGFzcyBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub2Zmc2V0OTAgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgY29uc3QgYWxscGFzc0JhbmsxVmFsdWVzID0gWzAuNjkyMzg3OCwgMC45MzYwNjU0MzIyOTU5LCAwLjk4ODIyOTUyMjY4NjAsIDAuOTk4NzQ4ODQ1MjczN107XG4gICAgICAgIGNvbnN0IGFsbHBhc3NCYW5rMlZhbHVlcyA9IFswLjQwMjE5MjExNjI0MjYsIDAuODU2MTcxMDg4MjQyMCwgMC45NzIyOTA5NTQ1NjUxLCAwLjk5NTI4ODQ3OTEyNzhdO1xuICAgICAgICB0aGlzLl9iYW5rMCA9IHRoaXMuX2NyZWF0ZUFsbFBhc3NGaWx0ZXJCYW5rKGFsbHBhc3NCYW5rMVZhbHVlcyk7XG4gICAgICAgIHRoaXMuX2JhbmsxID0gdGhpcy5fY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYWxscGFzc0JhbmsyVmFsdWVzKTtcbiAgICAgICAgdGhpcy5fb25lU2FtcGxlRGVsYXkgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFswLjAsIDEuMF0sIFsxLjAsIDAuMF0pO1xuICAgICAgICAvLyBjb25uZWN0IEFsbHBhc3MgZmlsdGVyIGJhbmtzXG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5fYmFuazAsIHRoaXMuX29uZVNhbXBsZURlbGF5LCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5fYmFuazEsIHRoaXMub2Zmc2V0OTApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYWxsIG9mIHRoZSBJSVIgZmlsdGVycyBmcm9tIGFuIGFycmF5IG9mIHZhbHVlcyB1c2luZyB0aGUgY29lZmZpY2llbnQgY2FsY3VsYXRpb24uXG4gICAgICovXG4gICAgX2NyZWF0ZUFsbFBhc3NGaWx0ZXJCYW5rKGJhbmtWYWx1ZXMpIHtcbiAgICAgICAgY29uc3Qgbm9kZXMgPSBiYW5rVmFsdWVzLm1hcCh2YWx1ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb2VmZmljaWVudHMgPSBbW3ZhbHVlICogdmFsdWUsIDAsIC0xXSwgWzEsIDAsIC0odmFsdWUgKiB2YWx1ZSldXTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGNvZWZmaWNpZW50c1swXSwgY29lZmZpY2llbnRzWzFdKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9mZnNldDkwLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYmFuazAuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fYmFuazEuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fb25lU2FtcGxlRGVsYXkuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaGFzZVNoaWZ0QWxscGFzcy5qcy5tYXAiLCJpbXBvcnQgeyBQaGFzZVNoaWZ0QWxscGFzcyB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL1BoYXNlU2hpZnRBbGxwYXNzXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvRWZmZWN0XCI7XG5pbXBvcnQgeyBBZGQgfSBmcm9tIFwiLi4vc2lnbmFsL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBOZWdhdGUgfSBmcm9tIFwiLi4vc2lnbmFsL05lZ2F0ZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgVG9uZU9zY2lsbGF0b3JOb2RlIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuLyoqXG4gKiBGcmVxdWVuY3lTaGlmdGVyIGNhbiBiZSB1c2VkIHRvIHNoaWZ0IGFsbCBmcmVxdWVuY2llcyBvZiBhIHNpZ25hbCBieSBhIGZpeGVkIGFtb3VudC5cbiAqIFRoZSBhbW91bnQgY2FuIGJlIGNoYW5nZWQgYXQgYXVkaW8gcmF0ZSBhbmQgdGhlIGVmZmVjdCBpcyBhcHBsaWVkIGluIHJlYWwgdGltZS5cbiAqIFRoZSBmcmVxdWVuY3kgc2hpZnRpbmcgaXMgaW1wbGVtZW50ZWQgd2l0aCBhIHRlY2huaXF1ZSBjYWxsZWQgc2luZ2xlIHNpZGUgYmFuZCBtb2R1bGF0aW9uIHVzaW5nIGEgcmluZyBtb2R1bGF0b3IuXG4gKiBOb3RlOiBDb250cmFyeSB0byBwaXRjaCBzaGlmdGluZywgYWxsIGZyZXF1ZW5jaWVzIGFyZSBzaGlmdGVkIGJ5IHRoZSBzYW1lIGFtb3VudCxcbiAqIGRlc3Ryb3lpbmcgdGhlIGhhcm1vbmljIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZW0uIFRoaXMgbGVhZHMgdG8gdGhlIGNsYXNzaWMgcmluZyBtb2R1bGF0b3IgdGltYnJlIGRpc3RvcnRpb24uXG4gKiBUaGUgYWxnb3JpdGhtIHdpbGwgcHJvZHVjZXMgc29tZSBhbGlhc2luZyB0b3dhcmRzIHRoZSBoaWdoIGVuZCwgZXNwZWNpYWxseSBpZiB5b3VyIHNvdXJjZSBtYXRlcmlhbFxuICogY29udGFpbnMgYSBsb3Qgb2YgaGlnaCBmcmVxdWVuY2llcy4gVW5mb3J0dW5hdGVsbHkgdGhlIHdlYmF1ZGlvIEFQSSBkb2VzIG5vdCBzdXBwb3J0IHJlc2FtcGxpbmdcbiAqIGJ1ZmZlcnMgaW4gcmVhbCB0aW1lLCBzbyBpdCBpcyBub3QgcG9zc2libGUgdG8gZml4IGl0IHByb3Blcmx5LiBEZXBlbmRpbmcgb24gdGhlIHVzZSBjYXNlIGl0IG1pZ2h0XG4gKiBiZSBhbiBvcHRpb24gdG8gbG93IHBhc3MgZmlsdGVyIHlvdXIgaW5wdXQgYmVmb3JlIGZyZXF1ZW5jeSBzaGlmdGluZyBpdCB0byBnZXQgcmlkZSBvZiB0aGUgYWxpYXNpbmcuXG4gKiBZb3UgY2FuIGZpbmQgYSB2ZXJ5IGRldGFpbGVkIGRlc2NyaXB0aW9uIG9mIHRoZSBhbGdvcml0aG0gaGVyZTogaHR0cHM6Ly9sYXJ6ZWl0bGluLmdpdGh1Yi5pby9STUZTL1xuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBpbnB1dCA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMjMwLCBcInNhd3Rvb3RoXCIpLnN0YXJ0KCk7XG4gKiBjb25zdCBzaGlmdCA9IG5ldyBUb25lLkZyZXF1ZW5jeVNoaWZ0ZXIoNDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGlucHV0LmNvbm5lY3Qoc2hpZnQpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5U2hpZnRlciBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeVNoaWZ0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lTaGlmdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lTaGlmdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluVmFsdWU6IC10aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2luZSA9IG5ldyBUb25lT3NjaWxsYXRvck5vZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jb3NpbmUgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogLTkwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9uZWdhdGUgPSBuZXcgTmVnYXRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hZGQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIgPSBuZXcgUGhhc2VTaGlmdEFsbHBhc3MoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jb25uZWN0KHRoaXMuX3BoYXNlU2hpZnRlcik7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNhcnJpZXIgZnJlcXVlbmN5IHNpZ25hbCB0byB0aGUgdHdvIG9zY2lsbGF0b3JzXG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmZhbih0aGlzLl9zaW5lLmZyZXF1ZW5jeSwgdGhpcy5fY29zaW5lLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlci5vZmZzZXQ5MC5jb25uZWN0KHRoaXMuX2Nvc2luZU11bHRpcGx5KTtcbiAgICAgICAgdGhpcy5fY29zaW5lLmNvbm5lY3QodGhpcy5fY29zaW5lTXVsdGlwbHkuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLmNvbm5lY3QodGhpcy5fc2luZU11bHRpcGx5KTtcbiAgICAgICAgdGhpcy5fc2luZS5jb25uZWN0KHRoaXMuX3NpbmVNdWx0aXBseS5mYWN0b3IpO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkuY29ubmVjdCh0aGlzLl9uZWdhdGUpO1xuICAgICAgICB0aGlzLl9jb3NpbmVNdWx0aXBseS5jb25uZWN0KHRoaXMuX2FkZCk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZS5jb25uZWN0KHRoaXMuX2FkZC5hZGRlbmQpO1xuICAgICAgICB0aGlzLl9hZGQuY29ubmVjdCh0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBvc2NpbGxhdG9ycyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMuaW1tZWRpYXRlKCk7XG4gICAgICAgIHRoaXMuX3NpbmUuc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fY29zaW5lLnN0YXJ0KG5vdyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hZGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb3NpbmVNdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3lTaGlmdGVyLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTG93cGFzc0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuLyoqXG4gKiBBbiBhcnJheSBvZiBjb21iIGZpbHRlciBkZWxheSB2YWx1ZXMgZnJvbSBGcmVldmVyYiBpbXBsZW1lbnRhdGlvblxuICovXG5jb25zdCBjb21iRmlsdGVyVHVuaW5ncyA9IFsxNTU3IC8gNDQxMDAsIDE2MTcgLyA0NDEwMCwgMTQ5MSAvIDQ0MTAwLCAxNDIyIC8gNDQxMDAsIDEyNzcgLyA0NDEwMCwgMTM1NiAvIDQ0MTAwLCAxMTg4IC8gNDQxMDAsIDExMTYgLyA0NDEwMF07XG4vKipcbiAqIEFuIGFycmF5IG9mIGFsbHBhc3MgZmlsdGVyIGZyZXF1ZW5jeSB2YWx1ZXMgZnJvbSBGcmVldmVyYiBpbXBsZW1lbnRhdGlvblxuICovXG5jb25zdCBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMgPSBbMjI1LCA1NTYsIDQ0MSwgMzQxXTtcbi8qKlxuICogRnJlZXZlcmIgaXMgYSByZXZlcmIgYmFzZWQgb24gW0ZyZWV2ZXJiXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRnJlZXZlcmIuaHRtbCkuXG4gKiBSZWFkIG1vcmUgb24gcmV2ZXJiIG9uIFtTb3VuZCBPbiBTb3VuZF0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDA0MDgzOTAyL2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbTo4MC9zb3MvZmViMDEvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmFzcCkuXG4gKiBGcmVldmVyYiBpcyBub3cgaW1wbGVtZW50ZWQgd2l0aCBhbiBBdWRpb1dvcmtsZXROb2RlIHdoaWNoIG1heSByZXN1bHQgb24gcGVyZm9ybWFuY2UgZGVncmFkYXRpb24gb24gc29tZSBwbGF0Zm9ybXMuIENvbnNpZGVyIHVzaW5nIFtbUmV2ZXJiXV0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZnJlZXZlcmIgPSBuZXcgVG9uZS5GcmVldmVyYigpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZyZWV2ZXJiLmRhbXBlbmluZyA9IDEwMDA7XG4gKiAvLyByb3V0aW5nIHN5bnRoIHRocm91Z2ggdGhlIHJldmVyYlxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkuY29ubmVjdChmcmVldmVyYik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgwLjA1KTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZWV2ZXJiIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiLCBcImRhbXBlbmluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZWV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGFsbHBhc3MgZmlsdGVycyBvbiB0aGUgbGVmdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSByaWdodFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCIsIFwiZGFtcGVuaW5nXCJdKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucm9vbVNpemUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSByaWdodFxuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMubWFwKGZyZXEgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWxscGFzc0wgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBhbGxwYXNzTC50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzTC5mcmVxdWVuY3kudmFsdWUgPSBmcmVxO1xuICAgICAgICAgICAgcmV0dXJuIGFsbHBhc3NMO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUiA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzUiA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3NSLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3NSLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzc1I7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMgPSBjb21iRmlsdGVyVHVuaW5ncy5tYXAoKGRlbGF5VGltZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxmcGYgPSBuZXcgTG93cGFzc0NvbWJGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBkYW1wZW5pbmc6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgICAgIGRlbGF5VGltZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgY29tYkZpbHRlclR1bmluZ3MubGVuZ3RoIC8gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQobGZwZiwgLi4udGhpcy5fYWxscGFzc0ZpbHRlcnNMKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KGxmcGYsIC4uLnRoaXMuX2FsbHBhc3NGaWx0ZXJzUik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJvb21TaXplLmNvbm5lY3QobGZwZi5yZXNvbmFuY2UpO1xuICAgICAgICAgICAgcmV0dXJuIGxmcGY7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHJvb21TaXplOiAwLjcsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IDMwMDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgZGFtcGVuaW5nIG9mIHRoZSByZXZlcmJlcmFudCBzaWduYWwuXG4gICAgICovXG4gICAgZ2V0IGRhbXBlbmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbWJGaWx0ZXJzWzBdLmRhbXBlbmluZztcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhkKSB7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzLmZvckVhY2goYyA9PiBjLmRhbXBlbmluZyA9IGQpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTC5mb3JFYWNoKGFsID0+IGFsLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUi5mb3JFYWNoKGFyID0+IGFyLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzLmZvckVhY2goY2YgPT4gY2YuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZWV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBGZWVkYmFja0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXJcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogYW4gYXJyYXkgb2YgdGhlIGNvbWIgZmlsdGVyIGRlbGF5IHRpbWUgdmFsdWVzXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJEZWxheVRpbWVzID0gWzE2ODcgLyAyNTAwMCwgMTYwMSAvIDI1MDAwLCAyMDUzIC8gMjUwMDAsIDIyNTEgLyAyNTAwMF07XG4vKipcbiAqIHRoZSByZXNvbmFuY2VzIG9mIGVhY2ggb2YgdGhlIGNvbWIgZmlsdGVyc1xuICovXG5jb25zdCBjb21iRmlsdGVyUmVzb25hbmNlcyA9IFswLjc3MywgMC44MDIsIDAuNzUzLCAwLjczM107XG4vKipcbiAqIHRoZSBhbGxwYXNzIGZpbHRlciBmcmVxdWVuY2llc1xuICovXG5jb25zdCBhbGxwYXNzRmlsdGVyRnJlcXMgPSBbMzQ3LCAxMTMsIDM3XTtcbi8qKlxuICogSkNSZXZlcmIgaXMgYSBzaW1wbGUgW1NjaHJvZWRlciBSZXZlcmJlcmF0b3JdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9TY2hyb2VkZXJfUmV2ZXJiZXJhdG9ycy5odG1sKVxuICogdHVuZWQgYnkgSm9obiBDaG93bmluZyBpbiAxOTcwLlxuICogSXQgaXMgbWFkZSB1cCBvZiB0aHJlZSBhbGxwYXNzIGZpbHRlcnMgYW5kIGZvdXIgW1tGZWVkYmFja0NvbWJGaWx0ZXJdXS5cbiAqIEpDUmV2ZXJiIGlzIG5vdyBpbXBsZW1lbnRlZCB3aXRoIGFuIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggbWF5IHJlc3VsdCBvbiBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiBvbiBzb21lIHBsYXRmb3Jtcy4gQ29uc2lkZXIgdXNpbmcgW1tSZXZlcmJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZXZlcmIgPSBuZXcgVG9uZS5KQ1JldmVyYigwLjQpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGRlbGF5ID0gbmV3IFRvbmUuRmVlZGJhY2tEZWxheSgwLjUpO1xuICogLy8gY29ubmVjdGluZyB0aGUgc3ludGggdG8gcmV2ZXJiIHRocm91Z2ggZGVsYXlcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuRHVvU3ludGgoKS5jaGFpbihkZWxheSwgcmV2ZXJiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTRcIiwgXCI4blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBKQ1JldmVyYiBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEpDUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJKQ1JldmVyYlwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogYSBzZXJpZXMgb2YgYWxscGFzcyBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogcGFyYWxsZWwgZmVlZGJhY2sgY29tYiBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhKQ1JldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCJdKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucm9vbVNpemUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZSA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IC0wLjczMyxcbiAgICAgICAgICAgIG1heDogMC4xOTcsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnNcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMgPSBhbGxwYXNzRmlsdGVyRnJlcXMubWFwKGZyZXEgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWxscGFzcyA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3MudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzcy5mcmVxdWVuY3kudmFsdWUgPSBmcmVxO1xuICAgICAgICAgICAgcmV0dXJuIGFsbHBhc3M7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBhbmQgdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzID0gY29tYkZpbHRlckRlbGF5VGltZXMubWFwKChkZWxheVRpbWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmYmNmID0gbmV3IEZlZWRiYWNrQ29tYkZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGRlbGF5VGltZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZS5jb25uZWN0KGZiY2YucmVzb25hbmNlKTtcbiAgICAgICAgICAgIGZiY2YucmVzb25hbmNlLnZhbHVlID0gY29tYkZpbHRlclJlc29uYW5jZXNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgY29tYkZpbHRlckRlbGF5VGltZXMubGVuZ3RoIC8gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQoLi4udGhpcy5fYWxscGFzc0ZpbHRlcnMsIGZiY2YpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQoLi4udGhpcy5fYWxscGFzc0ZpbHRlcnMsIGZiY2YpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZiY2Y7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjaGFpbiB0aGUgYWxscGFzcyBmaWx0ZXJzIHRvZ2V0aGVyXG4gICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdCh0aGlzLl9zY2FsZVJvb21TaXplKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicm9vbVNpemVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICByb29tU2l6ZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycy5mb3JFYWNoKGFwZiA9PiBhcGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tDb21iRmlsdGVycy5mb3JFYWNoKGZiY2YgPT4gZmJjZi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUpDUmV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogSnVzdCBsaWtlIGEgW1tTdGVyZW9GZWVkYmFja0VmZmVjdF1dLCBidXQgdGhlIGZlZWRiYWNrIGlzIHJvdXRlZCBmcm9tIGxlZnQgdG8gcmlnaHRcbiAqIGFuZCByaWdodCB0byBsZWZ0IGluc3RlYWQgb2Ygb24gdGhlIHNhbWUgY2hhbm5lbC5cbiAqIGBgYFxuICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyBmZWVkYmFja0wgPC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogKy0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tPiAgICAgICAgKy0tLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0rXG4gKiAgICAgIGZlZWRiYWNrTWVyZ2UgKy0tPiBzcGxpdCAgICAgICAgKEVGRkVDVCkgICAgICAgbWVyZ2UgKy0tPiBmZWVkYmFja1NwbGl0ICAgICB8IHxcbiAqICstLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLT4gICAgICAgICstLS0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLSsgfFxuICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIGZlZWRiYWNrUiA8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IGV4dGVuZHMgU3RlcmVvRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDEpO1xuICAgICAgICAvLyB0aGUgbGVmdCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSByaWdodCBpbnB1dFxuICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAwKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZmVlZGJhY2tcIl0pO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb1hGZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9YRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9YRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQaW5nUG9uZ0RlbGF5IGlzIGEgZmVlZGJhY2sgZGVsYXkgZWZmZWN0IHdoZXJlIHRoZSBlY2hvIGlzIGhlYXJkXG4gKiBmaXJzdCBpbiBvbmUgY2hhbm5lbCBhbmQgbmV4dCBpbiB0aGUgb3Bwb3NpdGUgY2hhbm5lbC4gSW4gYSBzdGVyZW9cbiAqIHN5c3RlbSB0aGVzZSBhcmUgdGhlIHJpZ2h0IGFuZCBsZWZ0IGNoYW5uZWxzLlxuICogUGluZ1BvbmdEZWxheSBpbiBtb3JlIHNpbXBsaWZpZWQgdGVybXMgaXMgdHdvIFRvbmUuRmVlZGJhY2tEZWxheXNcbiAqIHdpdGggaW5kZXBlbmRlbnQgZGVsYXkgdmFsdWVzLiBFYWNoIGRlbGF5IGlzIHJvdXRlZCB0byBvbmUgY2hhbm5lbFxuICogKGxlZnQgb3IgcmlnaHQpLCBhbmQgdGhlIGNoYW5uZWwgdHJpZ2dlcmVkIHNlY29uZCB3aWxsIGFsd2F5c1xuICogdHJpZ2dlciBhdCB0aGUgc2FtZSBpbnRlcnZhbCBhZnRlciB0aGUgZmlyc3QuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGluZ1BvbmcgPSBuZXcgVG9uZS5QaW5nUG9uZ0RlbGF5KFwiNG5cIiwgMC4yKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBkcnVtID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCgpLmNvbm5lY3QocGluZ1BvbmcpO1xuICogZHJ1bS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiMzJuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUGluZ1BvbmdEZWxheSBleHRlbmRzIFN0ZXJlb1hGZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpbmdQb25nRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBpbmdQb25nRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpbmdQb25nRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSk7XG4gICAgICAgIHRoaXMuX2xlZnREZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0RGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0UHJlRGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fbGVmdERlbGF5KTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fcmlnaHRQcmVEZWxheSwgdGhpcy5fcmlnaHREZWxheSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmZhbih0aGlzLl9sZWZ0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodERlbGF5LmRlbGF5VGltZSwgdGhpcy5fcmlnaHRQcmVEZWxheS5kZWxheVRpbWUpO1xuICAgICAgICAvLyByZWFycmFuZ2VkIHRoZSBmZWVkYmFjayB0byBiZSBhZnRlciB0aGUgcmlnaHRQcmVEZWxheVxuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuY29ubmVjdCh0aGlzLl9yaWdodERlbGF5KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZGVsYXlUaW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9YRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjI1LFxuICAgICAgICAgICAgbWF4RGVsYXk6IDFcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGVmdERlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHREZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0UHJlRGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBpbmdQb25nRGVsYXkuanMubWFwIiwiaW1wb3J0IHsgRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG4vKipcbiAqIFBpdGNoU2hpZnQgZG9lcyBuZWFyLXJlYWx0aW1lIHBpdGNoIHNoaWZ0aW5nIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBUaGUgZWZmZWN0IGlzIGFjaGlldmVkIGJ5IHNwZWVkaW5nIHVwIG9yIHNsb3dpbmcgZG93biB0aGUgZGVsYXlUaW1lXG4gKiBvZiBhIERlbGF5Tm9kZSB1c2luZyBhIHNhd3Rvb3RoIHdhdmUuXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW3RoaXMgcGRmXShodHRwOi8vZHNwLWJvb2submFyb2QucnUvc291bmRwcm9jLnBkZikuXG4gKiBBZGRpdGlvbmFsIHJlZmVyZW5jZSBieSBbTWlsbGVyIFB1Y2tldF0oaHR0cDovL21zcC51Y3NkLmVkdS90ZWNobmlxdWVzL3YwLjExL2Jvb2staHRtbC9ub2RlMTE1Lmh0bWwpLlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUGl0Y2hTaGlmdCBleHRlbmRzIEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGl0Y2hTaGlmdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBpdGNoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGl0Y2hTaGlmdFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGl0Y2hTaGlmdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBpdGNoXCJdKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZGVsYXlBID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9BID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDAuMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIlxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2RlbGF5QS5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLl9kZWxheUIgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb0IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICAgICAgcGhhc2U6IDE4MFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2RlbGF5Qi5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGUgPSBuZXcgQ3Jvc3NGYWRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgICAgIHBoYXNlOiA5MFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5mYWRlKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tEZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBkZWxheVRpbWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9mZWVkYmFja0RlbGF5LmRlbGF5VGltZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgICAgIHRoaXMuX3BpdGNoID0gb3B0aW9ucy5waXRjaDtcbiAgICAgICAgdGhpcy5fd2luZG93U2l6ZSA9IG9wdGlvbnMud2luZG93U2l6ZTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgdHdvIGRlbGF5IGxpbmVzIHVwXG4gICAgICAgIHRoaXMuX2RlbGF5QS5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5hKTtcbiAgICAgICAgdGhpcy5fZGVsYXlCLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmIpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LmZhbih0aGlzLl9sZm9BLmZyZXF1ZW5jeSwgdGhpcy5fbGZvQi5mcmVxdWVuY3ksIHRoaXMuX2Nyb3NzRmFkZUxGTy5mcmVxdWVuY3kpO1xuICAgICAgICAvLyByb3V0ZSB0aGUgaW5wdXRcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmZhbih0aGlzLl9kZWxheUEsIHRoaXMuX2RlbGF5Qik7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5jaGFpbih0aGlzLl9mZWVkYmFja0RlbGF5LCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBMRk9zIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgdGhpcy5fbGZvQS5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9sZm9CLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTy5zdGFydChub3cpO1xuICAgICAgICAvLyBzZXQgdGhlIGluaXRpYWwgdmFsdWVcbiAgICAgICAgdGhpcy53aW5kb3dTaXplID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwaXRjaDogMCxcbiAgICAgICAgICAgIHdpbmRvd1NpemU6IDAuMSxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBpdGNoIHRoZSBpbmNvbWluZyBzaWduYWwgYnkgc29tZSBpbnRlcnZhbCAobWVhc3VyZWQgaW4gc2VtaS10b25lcykuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwaXRjaFNoaWZ0ID0gbmV3IFRvbmUuUGl0Y2hTaGlmdCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChwaXRjaFNoaWZ0KS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwaXRjaFNoaWZ0LnBpdGNoID0gLTEyOyAvLyBkb3duIG9uZSBvY3RhdmVcbiAgICAgKiBwaXRjaFNoaWZ0LnBpdGNoID0gNzsgLy8gdXAgYSBmaWZ0aFxuICAgICAqL1xuICAgIGdldCBwaXRjaCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BpdGNoO1xuICAgIH1cbiAgICBzZXQgcGl0Y2goaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fcGl0Y2ggPSBpbnRlcnZhbDtcbiAgICAgICAgbGV0IGZhY3RvciA9IDA7XG4gICAgICAgIGlmIChpbnRlcnZhbCA8IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWluID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWF4ID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWluID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWF4ID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIGZhY3RvciA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCAtIDEpICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWluID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWF4ID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWluID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWF4ID0gMDtcbiAgICAgICAgICAgIGZhY3RvciA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCkgLSAxO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS52YWx1ZSA9IGZhY3RvciAqICgxLjIgLyB0aGlzLl93aW5kb3dTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdpbmRvdyBzaXplIGNvcnJlc3BvbmRzIHJvdWdobHkgdG8gdGhlIHNhbXBsZSBsZW5ndGggaW4gYSBsb29waW5nIHNhbXBsZXIuXG4gICAgICogU21hbGxlciB2YWx1ZXMgYXJlIGRlc2lyYWJsZSBmb3IgYSBsZXNzIG5vdGljZWFibGUgZGVsYXkgdGltZSBvZiB0aGUgcGl0Y2ggc2hpZnRlZFxuICAgICAqIHNpZ25hbCwgYnV0IGxhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc21vb3RoZXIgcGl0Y2ggc2hpZnRpbmcgZm9yIGxhcmdlciBpbnRlcnZhbHMuXG4gICAgICogQSBub21pbmFsIHJhbmdlIG9mIDAuMDMgdG8gMC4xIGlzIHJlY29tbWVuZGVkLlxuICAgICAqL1xuICAgIGdldCB3aW5kb3dTaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2luZG93U2l6ZTtcbiAgICB9XG4gICAgc2V0IHdpbmRvd1NpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gdGhpcy50b1NlY29uZHMoc2l6ZSk7XG4gICAgICAgIHRoaXMucGl0Y2ggPSB0aGlzLl9waXRjaDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheUEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheUIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9BLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvQi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaXRjaFNoaWZ0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQaGFzZXIgaXMgYSBwaGFzZXIgZWZmZWN0LiBQaGFzZXJzIHdvcmsgYnkgY2hhbmdpbmcgdGhlIHBoYXNlXG4gKiBvZiBkaWZmZXJlbnQgZnJlcXVlbmN5IGNvbXBvbmVudHMgb2YgYW4gaW5jb21pbmcgc2lnbmFsLiBSZWFkIG1vcmUgb25cbiAqIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BoYXNlcl8oZWZmZWN0KSkuXG4gKiBJbnNwaXJhdGlvbiBmb3IgdGhpcyBwaGFzZXIgY29tZXMgZnJvbSBbVHVuYS5qc10oaHR0cHM6Ly9naXRodWIuY29tL0RpbmFobW9lL3R1bmEvKS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaGFzZXIgPSBuZXcgVG9uZS5QaGFzZXIoe1xuICogXHRmcmVxdWVuY3k6IDE1LFxuICogXHRvY3RhdmVzOiA1LFxuICogXHRiYXNlRnJlcXVlbmN5OiAxMDAwXG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KHBoYXNlcik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkUzXCIsIFwiMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaGFzZXIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaGFzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwiYmFzZUZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBoYXNlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGhhc2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcImJhc2VGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9SID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgcGhhc2U6IDE4MCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KG9wdGlvbnMuYmFzZUZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzTCA9IHRoaXMuX21ha2VGaWx0ZXJzKG9wdGlvbnMuc3RhZ2VzLCB0aGlzLl9sZm9MKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyc1IgPSB0aGlzLl9tYWtlRmlsdGVycyhvcHRpb25zLnN0YWdlcywgdGhpcy5fbGZvUik7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LnZhbHVlID0gb3B0aW9ucy5mcmVxdWVuY3k7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlbSB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KC4uLnRoaXMuX2ZpbHRlcnNMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQoLi4udGhpcy5fZmlsdGVyc1IpO1xuICAgICAgICAvLyBjb250cm9sIHRoZSBmcmVxdWVuY3kgd2l0aCBvbmUgTEZPXG4gICAgICAgIHRoaXMuX2xmb0wuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICAvLyBzZXQgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5iYXNlRnJlcXVlbmN5ID0gb3B0aW9ucy5iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBsZm9cbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCgpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAuNSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDMsXG4gICAgICAgICAgICBzdGFnZXM6IDEwLFxuICAgICAgICAgICAgUTogMTAsXG4gICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAzNTAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfbWFrZUZpbHRlcnMoc3RhZ2VzLCBjb25uZWN0VG9GcmVxKSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcnMgPSBbXTtcbiAgICAgICAgLy8gbWFrZSBhbGwgdGhlIGZpbHRlcnNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFnZXM7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgZmlsdGVyLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIHRoaXMuUS5jb25uZWN0KGZpbHRlci5RKTtcbiAgICAgICAgICAgIGNvbm5lY3RUb0ZyZXEuY29ubmVjdChmaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIGZpbHRlcnMucHVzaChmaWx0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhlIHBoYXNlIGdvZXMgYWJvdmUgdGhlIGJhc2VGcmVxdWVuY3lcbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcbiAgICAgICAgdGhpcy5fbGZvTC5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMuX2xmb1IubWF4ID0gbWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGhlIGJhc2UgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXJzLlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koZnJlcSkge1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShmcmVxKTtcbiAgICAgICAgdGhpcy5fbGZvTC5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9sZm9SLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzTC5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzUi5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBoYXNlci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5vaXNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Ob2lzZVwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFNpbXBsZSBjb252b2x1dGlvbiBjcmVhdGVkIHdpdGggZGVjYXlpbmcgbm9pc2UuXG4gKiBHZW5lcmF0ZXMgYW4gSW1wdWxzZSBSZXNwb25zZSBCdWZmZXJcbiAqIHdpdGggVG9uZS5PZmZsaW5lIHRoZW4gZmVlZHMgdGhlIElSIGludG8gQ29udm9sdmVyTm9kZS5cbiAqIFRoZSBpbXB1bHNlIHJlc3BvbnNlIGdlbmVyYXRpb24gaXMgYXN5bmMsIHNvIHlvdSBoYXZlXG4gKiB0byB3YWl0IHVudGlsIFtbcmVhZHldXSByZXNvbHZlcyBiZWZvcmUgaXQgd2lsbCBtYWtlIGEgc291bmQuXG4gKlxuICogSW5zcGlyYXRpb24gZnJvbSBbUmV2ZXJiR2VuXShodHRwczovL2dpdGh1Yi5jb20vYWRlbGVzcGluYXNzZS9yZXZlcmJHZW4pLlxuICogQ29weXJpZ2h0IChjKSAyMDE0IEFsYW4gZGVMZXNwaW5hc3NlIEFwYWNoZSAyLjAgTGljZW5zZS5cbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXZlcmIgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWNheVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJldmVyYlwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udm9sdmVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlc29sdmVzIHdoZW4gdGhlIHJldmVyYiBidWZmZXIgaXMgZ2VuZXJhdGVkLiBXaGVuZXZlciBlaXRoZXIgW1tkZWNheV1dXG4gICAgICAgICAqIG9yIFtbcHJlRGVsYXldXSBhcmUgc2V0LCB5b3UgaGF2ZSB0byB3YWl0IHVudGlsIFtbcmVhZHldXSByZXNvbHZlc1xuICAgICAgICAgKiBiZWZvcmUgdGhlIElSIGlzIGdlbmVyYXRlZCB3aXRoIHRoZSBsYXRlc3QgdmFsdWVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZWFkeSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVjYXlcIl0pO1xuICAgICAgICB0aGlzLl9kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG4gICAgICAgIHRoaXMuX3ByZURlbGF5ID0gb3B0aW9ucy5wcmVEZWxheTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fY29udm9sdmVyKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVjYXk6IDEuNSxcbiAgICAgICAgICAgIHByZURlbGF5OiAwLjAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSByZXZlcmIuXG4gICAgICovXG4gICAgZ2V0IGRlY2F5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjYXk7XG4gICAgfVxuICAgIHNldCBkZWNheSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UodGltZSwgMC4wMDEpO1xuICAgICAgICB0aGlzLl9kZWNheSA9IHRpbWU7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGJlZm9yZSB0aGUgcmV2ZXJiIGlzIGZ1bGx5IHJhbXBlZCBpbi5cbiAgICAgKi9cbiAgICBnZXQgcHJlRGVsYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVEZWxheTtcbiAgICB9XG4gICAgc2V0IHByZURlbGF5KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwKTtcbiAgICAgICAgdGhpcy5fcHJlRGVsYXkgPSB0aW1lO1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIHRoZSBJbXB1bHNlIFJlc3BvbnNlLiBSZXR1cm5zIGEgcHJvbWlzZSB3aGlsZSB0aGUgSVIgaXMgYmVpbmcgZ2VuZXJhdGVkLlxuICAgICAqIEByZXR1cm4gUHJvbWlzZSB3aGljaCByZXR1cm5zIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIGdlbmVyYXRlKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNSZWFkeSA9IHRoaXMucmVhZHk7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYSBub2lzZSBidXJzdCB3aGljaCBkZWNheXMgb3ZlciB0aGUgZHVyYXRpb24gaW4gZWFjaCBjaGFubmVsXG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDIsIHRoaXMuX2RlY2F5ICsgdGhpcy5fcHJlRGVsYXksIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIGNvbnN0IG5vaXNlTCA9IG5ldyBOb2lzZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBjb25zdCBub2lzZVIgPSBuZXcgTm9pc2UoeyBjb250ZXh0IH0pO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0IH0pO1xuICAgICAgICAgICAgbm9pc2VMLmNvbm5lY3QobWVyZ2UsIDAsIDApO1xuICAgICAgICAgICAgbm9pc2VSLmNvbm5lY3QobWVyZ2UsIDAsIDEpO1xuICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBuZXcgR2Fpbih7IGNvbnRleHQgfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICAgICAgbWVyZ2UuY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgICAgICBub2lzZUwuc3RhcnQoMCk7XG4gICAgICAgICAgICBub2lzZVIuc3RhcnQoMCk7XG4gICAgICAgICAgICAvLyBwcmVkZWxheVxuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCAwKTtcbiAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGhpcy5fcHJlRGVsYXkpO1xuICAgICAgICAgICAgLy8gZGVjYXlcbiAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKDAsIHRoaXMuX3ByZURlbGF5LCB0aGlzLmRlY2F5KTtcbiAgICAgICAgICAgIC8vIHJlbmRlciB0aGUgYnVmZmVyXG4gICAgICAgICAgICBjb25zdCByZW5kZXJQcm9taXNlID0gY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMucmVhZHkgPSByZW5kZXJQcm9taXNlLnRoZW4obm9PcCk7XG4gICAgICAgICAgICAvLyB3YWl0IGZvciB0aGUgcHJldmlvdXMgYHJlYWR5YCB0byByZXNvbHZlXG4gICAgICAgICAgICB5aWVsZCBwcmV2aW91c1JlYWR5O1xuICAgICAgICAgICAgLy8gc2V0IHRoZSBidWZmZXJcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSAoeWllbGQgcmVuZGVyUHJvbWlzZSkuZ2V0KCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UmV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4vU3BsaXRcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi8uLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG4gKiBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKS5cbiAqIGBgYFxuICogTWlkID0gKExlZnQrUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIG1pZC1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogU2lkZSA9IChMZWZ0LVJpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBzaWRlLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZVNwbGl0XCI7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gdGhpcy5pbnB1dCA9IG5ldyBTcGxpdCh7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkQWRkID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdCA9IG5ldyBTdWJ0cmFjdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX21pZEFkZCwgMCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLmFkZGVuZCwgMSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fc2lkZVN1YnRyYWN0LCAwKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3Quc3VidHJhaGVuZCwgMSk7XG4gICAgICAgIHRoaXMuX21pZEFkZC5jb25uZWN0KHRoaXMubWlkKTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmNvbm5lY3QodGhpcy5zaWRlKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZEFkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZVNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4vTWVyZ2VcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi8uLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1pZFNpZGVNZXJnZSBtZXJnZXMgdGhlIG1pZCBhbmQgc2lkZSBzaWduYWwgYWZ0ZXIgdGhleSd2ZSBiZWVuIHNlcGFyYXRlZCBieSBbW01pZFNpZGVTcGxpdF1dXG4gKiBgYGBcbiAqIE1pZCA9IChMZWZ0K1JpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBtaWQtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIFNpZGUgPSAoTGVmdC1SaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gc2lkZS1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlTWVyZ2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZU1lcmdlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVNZXJnZVwiO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQuZmFuKHRoaXMuX2xlZnQpO1xuICAgICAgICB0aGlzLnNpZGUuY29ubmVjdCh0aGlzLl9sZWZ0LmFkZGVuZCk7XG4gICAgICAgIHRoaXMubWlkLmNvbm5lY3QodGhpcy5fcmlnaHQpO1xuICAgICAgICB0aGlzLnNpZGUuY29ubmVjdCh0aGlzLl9yaWdodC5zdWJ0cmFoZW5kKTtcbiAgICAgICAgdGhpcy5fbGVmdC5jb25uZWN0KHRoaXMuX2xlZnRNdWx0KTtcbiAgICAgICAgdGhpcy5fcmlnaHQuY29ubmVjdCh0aGlzLl9yaWdodE11bHQpO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAwKTtcbiAgICAgICAgdGhpcy5fcmlnaHRNdWx0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlTWVyZ2UuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBNaWRTaWRlU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5pbXBvcnQgeyBNaWRTaWRlTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG4vKipcbiAqIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsXG4gKiAod2hpY2ggY29tZXMgb3V0IG9mIGJvdGggdGhlIGxlZnQgYW5kIHRoZSByaWdodCBjaGFubmVsKVxuICogYW5kIHRoZSAnc2lkZScgKHdoaWNoIG9ubHkgY29tZXMgb3V0IG9mIHRoZSB0aGUgc2lkZSBjaGFubmVscylcbiAqIGFuZCBlZmZlY3RzIHRoZW0gc2VwYXJhdGVseSBiZWZvcmUgYmVpbmcgcmVjb21iaW5lZC5cbiAqIEFwcGxpZXMgYSBNaWQvU2lkZSBzZXBlcmF0aW9uIGFuZCByZWNvbWJpbmF0aW9uLlxuICogQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuICogVGhpcyBpcyBhIGJhc2UtY2xhc3MgZm9yIE1pZC9TaWRlIEVmZmVjdHMuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlRWZmZWN0IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVFZmZlY3RcIjtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlID0gbmV3IE1pZFNpZGVNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0ID0gbmV3IE1pZFNpZGVTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2VuZCA9IHRoaXMuX21pZFNpZGVTcGxpdC5taWQ7XG4gICAgICAgIHRoaXMuX3NpZGVTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0LnNpZGU7XG4gICAgICAgIHRoaXMuX21pZFJldHVybiA9IHRoaXMuX21pZFNpZGVNZXJnZS5taWQ7XG4gICAgICAgIHRoaXMuX3NpZGVSZXR1cm4gPSB0aGlzLl9taWRTaWRlTWVyZ2Uuc2lkZTtcbiAgICAgICAgLy8gdGhlIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jb25uZWN0KHRoaXMuX21pZFNpZGVTcGxpdCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgbWlkIGNoYWluIG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0TWlkKC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX21pZFNlbmQuY2hhaW4oLi4ubm9kZXMsIHRoaXMuX21pZFJldHVybik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIHNpZGUgY2hhaW4gb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RTaWRlKC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NpZGVTZW5kLmNoYWluKC4uLm5vZGVzLCB0aGlzLl9zaWRlUmV0dXJuKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTZW5kLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlUmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZUVmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBNaWRTaWRlRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9NaWRTaWRlRWZmZWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuLi9zaWduYWwvU3VidHJhY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBcHBsaWVzIGEgd2lkdGggZmFjdG9yIHRvIHRoZSBtaWQvc2lkZSBzZXBlcmF0aW9uLlxuICogMCBpcyBhbGwgbWlkIGFuZCAxIGlzIGFsbCBzaWRlLlxuICogQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuICogYGBgXG4gKiBNaWQgKj0gMiooMS13aWR0aCk8YnI+XG4gKiBTaWRlICo9IDIqd2lkdGhcbiAqIGBgYFxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvV2lkZW5lciBleHRlbmRzIE1pZFNpZGVFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTdGVyZW9XaWRlbmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wid2lkdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGVyZW9XaWRlbmVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTdGVyZW9XaWRlbmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wid2lkdGhcIl0pO1xuICAgICAgICB0aGlzLndpZHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy53aWR0aCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pZE11bHQgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQuY29ubmVjdCh0aGlzLl9taWRNdWx0LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdE1pZCh0aGlzLl9taWRNdWx0KTtcbiAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aCA9IG5ldyBTdWJ0cmFjdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aC5jb25uZWN0KHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQpO1xuICAgICAgICBjb25uZWN0KHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKSwgdGhpcy5fb25lTWludXNXaWR0aCk7XG4gICAgICAgIHRoaXMud2lkdGguY29ubmVjdCh0aGlzLl9vbmVNaW51c1dpZHRoLnN1YnRyYWhlbmQpO1xuICAgICAgICB0aGlzLl9zaWRlTXVsdCA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy53aWR0aC5jb25uZWN0KHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuY29ubmVjdCh0aGlzLl9zaWRlTXVsdC5mYWN0b3IpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RTaWRlKHRoaXMuX3NpZGVNdWx0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNaWRTaWRlRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHdpZHRoOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2lkdGguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRNdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZU11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoTWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvV2lkZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVHJlbW9sbyBtb2R1bGF0ZXMgdGhlIGFtcGxpdHVkZSBvZiBhbiBpbmNvbWluZyBzaWduYWwgdXNpbmcgYW4gW1tMRk9dXS5cbiAqIFRoZSBlZmZlY3QgaXMgYSBzdGVyZW8gZWZmZWN0IHdoZXJlIHRoZSBtb2R1bGF0aW9uIHBoYXNlIGlzIGludmVydGVkIGluIGVhY2ggY2hhbm5lbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gY3JlYXRlIGEgdHJlbW9sbyBhbmQgc3RhcnQgaXQncyBMRk9cbiAqIGNvbnN0IHRyZW1vbG8gPSBuZXcgVG9uZS5UcmVtb2xvKDksIDAuNzUpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSB0cmVtb2xvIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHRyZW1vbG8pLnN0YXJ0KCk7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgVHJlbW9sbyBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyZW1vbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyZW1vbG9cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyZW1vbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMSxcbiAgICAgICAgICAgIG1heDogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMSxcbiAgICAgICAgICAgIG1heDogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUwgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlUiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlcHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXB0aCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fYW1wbGl0dWRlTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX2FtcGxpdHVkZVIpO1xuICAgICAgICB0aGlzLl9sZm9MLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlTC5nYWluKTtcbiAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZVIuZ2Fpbik7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmZhbih0aGlzLl9sZm9MLmZyZXF1ZW5jeSwgdGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmRlcHRoLmZhbih0aGlzLl9sZm9SLmFtcGxpdHVkZSwgdGhpcy5fbGZvTC5hbXBsaXR1ZGUpO1xuICAgICAgICB0aGlzLnNwcmVhZCA9IG9wdGlvbnMuc3ByZWFkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICBkZXB0aDogMC41LFxuICAgICAgICAgICAgc3ByZWFkOiAxODAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgdHJlbW9sby5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSB0cmVtb2xvLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGVmZmVjdCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnN5bmMoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb0wudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9sZm9SLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbW91bnQgb2Ygc3RlcmVvIHNwcmVhZC4gV2hlbiBzZXQgdG8gMCwgYm90aCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBjZW50cmFsbHkuXG4gICAgICogV2hlbiBzZXQgdG8gMTgwLCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBoYXJkIGxlZnQgYW5kIHJpZ2h0IHJlc3BlY3RpdmVseS5cbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvUi5waGFzZSAtIHRoaXMuX2xmb0wucGhhc2U7IC8vIDE4MFxuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICB0aGlzLl9sZm9MLnBoYXNlID0gOTAgLSAoc3ByZWFkIC8gMik7XG4gICAgICAgIHRoaXMuX2xmb1IucGhhc2UgPSAoc3ByZWFkIC8gMikgKyA5MDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJlbW9sby5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEEgVmlicmF0byBlZmZlY3QgY29tcG9zZWQgb2YgYSBUb25lLkRlbGF5IGFuZCBhIFRvbmUuTEZPLiBUaGUgTEZPXG4gKiBtb2R1bGF0ZXMgdGhlIGRlbGF5VGltZSBvZiB0aGUgZGVsYXksIGNhdXNpbmcgdGhlIHBpdGNoIHRvIHJpc2UgYW5kIGZhbGwuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBWaWJyYXRvIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVmlicmF0by5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVmlicmF0b1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVmlicmF0by5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgcGhhc2U6IC05MCAvLyBvZmZzZSB0aGUgcGhhc2Ugc28gdGhlIHJlc3RpbmcgcG9zaXRpb24gaXMgaW4gdGhlIGNlbnRlclxuICAgICAgICB9KS5zdGFydCgpLmNvbm5lY3QodGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2xmby5hbXBsaXR1ZGU7XG4gICAgICAgIHRoaXMuZGVwdGgudmFsdWUgPSBvcHRpb25zLmRlcHRoO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9kZWxheU5vZGUsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4RGVsYXk6IDAuMDA1LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA1LFxuICAgICAgICAgICAgZGVwdGg6IDAuMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIG9zY2lsbGF0b3IgYXR0YWNoZWQgdG8gdGhlIFZpYnJhdG8uXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VmlicmF0by5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BdXRvRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BdXRvUGFubmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BdXRvV2FoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9CaXRDcnVzaGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9DaGVieXNoZXZcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Nob3J1c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vRGlzdG9ydGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRmVlZGJhY2tEZWxheVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRnJlcXVlbmN5U2hpZnRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRnJlZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0pDUmV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaW5nUG9uZ0RlbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaXRjaFNoaWZ0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaGFzZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1JldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3RlcmVvV2lkZW5lclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVHJlbW9sb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vVmlicmF0b1wiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIFtBbmFseXNlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jaWRsLWRlZi1BbmFseXNlck5vZGUpLlxuICogRXh0cmFjdHMgRkZUIG9yIFdhdmVmb3JtIGRhdGEgZnJvbSB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQW5hbHlzZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQW5hbHlzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCIsIFwic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFuYWx5c2VyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW5hbHlzZXIgbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FuYWx5c2VycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGJ1ZmZlciB0aGF0IHRoZSBGRlQgZGF0YSBpcyB3cml0dGVuIHRvXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBbmFseXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIiwgXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fZ2FpbiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9zcGxpdCA9IG5ldyBTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjaGFubmVsczogb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIGFzc2VydFJhbmdlKG9wdGlvbnMuY2hhbm5lbHMsIDEpO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGFuYWx5c2Vyc1xuICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IG9wdGlvbnMuY2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICAgICAgdGhpcy5fYW5hbHlzZXJzW2NoYW5uZWxdID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX2FuYWx5c2Vyc1tjaGFubmVsXSwgY2hhbm5lbCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZXMgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICAgICAgdHlwZTogXCJmZnRcIixcbiAgICAgICAgICAgIGNoYW5uZWxzOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUnVuIHRoZSBhbmFseXNpcyBnaXZlbiB0aGUgY3VycmVudCBzZXR0aW5ncy4gSWYgW1tjaGFubmVsc11dID0gMSxcbiAgICAgKiBpdCB3aWxsIHJldHVybiBhIEZsb2F0MzJBcnJheS4gSWYgW1tjaGFubmVsc11dID4gMSwgaXQgd2lsbFxuICAgICAqIHJldHVybiBhbiBhcnJheSBvZiBGbG9hdDMyQXJyYXlzIHdoZXJlIGVhY2ggaW5kZXggaW4gdGhlIGFycmF5XG4gICAgICogcmVwcmVzZW50cyB0aGUgYW5hbHlzaXMgZG9uZSBvbiBhIGNoYW5uZWwuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKChhbmFseXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcnNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwiZmZ0XCIpIHtcbiAgICAgICAgICAgICAgICBhbmFseXNlci5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoYnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFwid2F2ZWZvcm1cIikge1xuICAgICAgICAgICAgICAgIGFuYWx5c2VyLmdldEZsb2F0VGltZURvbWFpbkRhdGEoYnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLmNoYW5uZWxzID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyc1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKChhbmFseXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGFuYWx5c2VyLmZmdFNpemUgPSBzaXplICogMjtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnNbaW5kZXhdID0gbmV3IEZsb2F0MzJBcnJheShzaXplKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgdGhlIGFuYWx5c2VyIGRvZXMgdGhlIGFuYWx5c2lzIG9uLiBDaGFubmVsXG4gICAgICogc2VwYXJhdGlvbiBpcyBkb25lIHVzaW5nIFtbU3BsaXRdXVxuICAgICAqL1xuICAgIGdldCBjaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vycy5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmFseXNpcyBmdW5jdGlvbiByZXR1cm5lZCBieSBhbmFseXNlci5nZXRWYWx1ZSgpLCBlaXRoZXIgXCJmZnRcIiBvciBcIndhdmVmb3JtXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGFzc2VydCh0eXBlID09PSBcIndhdmVmb3JtXCIgfHwgdHlwZSA9PT0gXCJmZnRcIiwgYEFuYWx5c2VyOiBpbnZhbGlkIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIDAgcmVwcmVzZW50cyBubyB0aW1lIGF2ZXJhZ2luZyB3aXRoIHRoZSBsYXN0IGFuYWx5c2lzIGZyYW1lLlxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnNbMF0uc21vb3RoaW5nVGltZUNvbnN0YW50O1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHZhbCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaChhID0+IGEuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gdmFsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaChhID0+IGEuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QW5hbHlzZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBBbmFseXNlciB9IGZyb20gXCIuL0FuYWx5c2VyXCI7XG4vKipcbiAqIFRoZSBiYXNlIGNsYXNzIGZvciBNZXRlcmluZyBjbGFzc2VzLlxuICovXG5leHBvcnQgY2xhc3MgTWV0ZXJCYXNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXRlckJhc2VcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fYW5hbHlzZXIgPSBuZXcgQW5hbHlzZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc2l6ZTogMjU2LFxuICAgICAgICAgICAgdHlwZTogXCJ3YXZlZm9ybVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGVyQmFzZS5qcy5tYXAiLCJpbXBvcnQgeyBnYWluVG9EYiB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG5pbXBvcnQgeyB3YXJuIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgQW5hbHlzZXIgfSBmcm9tIFwiLi9BbmFseXNlclwiO1xuLyoqXG4gKiBNZXRlciBnZXRzIHRoZSBbUk1TXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Sb290X21lYW5fc3F1YXJlKVxuICogb2YgYW4gaW5wdXQgc2lnbmFsLiBJdCBjYW4gYWxzbyBnZXQgdGhlIHJhdyB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXRlciA9IG5ldyBUb25lLk1ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAqIG1pYy5vcGVuKCk7XG4gKiAvLyBjb25uZWN0IG1pYyB0byB0aGUgbWV0ZXJcbiAqIG1pYy5jb25uZWN0KG1ldGVyKTtcbiAqIC8vIHRoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWNcbiAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKG1ldGVyLmdldFZhbHVlKCkpLCAxMDApO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWV0ZXIgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNtb290aGluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcHJldmlvdXMgZnJhbWUncyB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcm1zID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fYW5hbHlzZXIgPSBuZXcgQW5hbHlzZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc2l6ZTogMjU2LFxuICAgICAgICAgICAgdHlwZTogXCJ3YXZlZm9ybVwiLFxuICAgICAgICAgICAgY2hhbm5lbHM6IG9wdGlvbnMuY2hhbm5lbHMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNtb290aGluZyA9IG9wdGlvbnMuc21vb3RoaW5nLFxuICAgICAgICAgICAgdGhpcy5ub3JtYWxSYW5nZSA9IG9wdGlvbnMubm9ybWFsUmFuZ2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICAgICAgbm9ybWFsUmFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgY2hhbm5lbHM6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVc2UgW1tnZXRWYWx1ZV1dIGluc3RlYWQuIEZvciB0aGUgcHJldmlvdXMgZ2V0VmFsdWUgYmVoYXZpb3IsIHVzZSBEQ01ldGVyLlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgZ2V0TGV2ZWwoKSB7XG4gICAgICAgIHdhcm4oXCInZ2V0TGV2ZWwnIGhhcyBiZWVuIGNoYW5nZWQgdG8gJ2dldFZhbHVlJ1wiKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gICAgICogT3V0cHV0IGlzIGluIGRlY2liZWxzIHdoZW4gW1tub3JtYWxSYW5nZV1dIGlzIGBmYWxzZWAuXG4gICAgICogSWYgW1tjaGFubmVsc11dID0gMSwgdGhlbiB0aGUgb3V0cHV0IGlzIGEgc2luZ2xlIG51bWJlclxuICAgICAqIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhlIGlucHV0IHNpZ25hbC4gV2hlbiBbW2NoYW5uZWxzXV0gPiAxLFxuICAgICAqIHRoZW4gZWFjaCBjaGFubmVsIGlzIHJldHVybmVkIGFzIGEgdmFsdWUgaW4gYSBudW1iZXIgYXJyYXkuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IGFWYWx1ZXMgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCBjaGFubmVsVmFsdWVzID0gdGhpcy5jaGFubmVscyA9PT0gMSA/IFthVmFsdWVzXSA6IGFWYWx1ZXM7XG4gICAgICAgIGNvbnN0IHZhbHMgPSBjaGFubmVsVmFsdWVzLm1hcCh2YWx1ZXMgPT4ge1xuICAgICAgICAgICAgY29uc3QgdG90YWxTcXVhcmVkID0gdmFsdWVzLnJlZHVjZSgodG90YWwsIGN1cnJlbnQpID0+IHRvdGFsICsgY3VycmVudCAqIGN1cnJlbnQsIDApO1xuICAgICAgICAgICAgY29uc3Qgcm1zID0gTWF0aC5zcXJ0KHRvdGFsU3F1YXJlZCAvIHZhbHVlcy5sZW5ndGgpO1xuICAgICAgICAgICAgLy8gdGhlIHJtcyBjYW4gb25seSBmYWxsIGF0IHRoZSByYXRlIG9mIHRoZSBzbW9vdGhpbmdcbiAgICAgICAgICAgIC8vIGJ1dCBjYW4ganVtcCB1cCBpbnN0YW50bHlcbiAgICAgICAgICAgIHRoaXMuX3JtcyA9IE1hdGgubWF4KHJtcywgdGhpcy5fcm1zICogdGhpcy5zbW9vdGhpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsUmFuZ2UgPyB0aGlzLl9ybXMgOiBnYWluVG9EYih0aGlzLl9ybXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWxzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFubmVscyBvZiBhbmFseXNpcy5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5jaGFubmVscztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRiVG9HYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGZyZXF1ZW5jeSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlIHVzaW5nIGEgZmFzdCBGb3VyaWVyIHRyYW5zZm9ybS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZGVCBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZGVC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGRlRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZGVC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pO1xuICAgICAgICB0aGlzLm5vcm1hbFJhbmdlID0gb3B0aW9ucy5ub3JtYWxSYW5nZTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwiZmZ0XCI7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG5vcm1hbFJhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgIHNpemU6IDEwMjQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuOCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGN1cnJlbnQgZnJlcXVlbmN5IGRhdGEgZnJvbSB0aGUgY29ubmVjdGVkIGF1ZGlvIHNvdXJjZS5cbiAgICAgKiBSZXR1cm5zIHRoZSBmcmVxdWVuY3kgZGF0YSBvZiBsZW5ndGggW1tzaXplXV0gYXMgYSBGbG9hdDMyQXJyYXkgb2YgZGVjaWJlbCB2YWx1ZXMuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIHJldHVybiB2YWx1ZXMubWFwKHYgPT4gdGhpcy5ub3JtYWxSYW5nZSA/IGRiVG9HYWluKHYpIDogdik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqIERldGVybWluZXMgdGhlIHNpemUgb2YgdGhlIGFycmF5IHJldHVybmVkIGJ5IFtbZ2V0VmFsdWVdXSAoaS5lLiB0aGUgbnVtYmVyIG9mXG4gICAgICogZnJlcXVlbmN5IGJpbnMpLiBMYXJnZSBGRlQgc2l6ZXMgbWF5IGJlIGNvc3RseSB0byBjb21wdXRlLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc2l6ZTtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyh2YWwpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBmcmVxdWVuY3kgdmFsdWUgaW4gaGVydHogb2YgZWFjaCBvZiB0aGUgaW5kaWNlcyBvZiB0aGUgRkZUJ3MgW1tnZXRWYWx1ZV1dIHJlc3BvbnNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmZ0ID0gbmV3IFRvbmUuRkZUKDMyKTtcbiAgICAgKiBjb25zb2xlLmxvZyhbMCwgMSwgMiwgMywgNF0ubWFwKGluZGV4ID0+IGZmdC5nZXRGcmVxdWVuY3lPZkluZGV4KGluZGV4KSkpO1xuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeU9mSW5kZXgoaW5kZXgpIHtcbiAgICAgICAgYXNzZXJ0KDAgPD0gaW5kZXggJiYgaW5kZXggPCB0aGlzLnNpemUsIGBpbmRleCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzIHRoYW4gJHt0aGlzLnNpemV9YCk7XG4gICAgICAgIHJldHVybiBpbmRleCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gKHRoaXMuc2l6ZSAqIDIpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZGVC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuLyoqXG4gKiBEQ01ldGVyIGdldHMgdGhlIHJhdyB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsIGF0IHRoZSBjdXJyZW50IHRpbWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuRENNZXRlcigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG4gKiBtaWMub3BlbigpO1xuICogLy8gY29ubmVjdCBtaWMgdG8gdGhlIG1ldGVyXG4gKiBtaWMuY29ubmVjdChtZXRlcik7XG4gKiAvLyB0aGUgY3VycmVudCBsZXZlbCBvZiB0aGUgbWljXG4gKiBjb25zdCBsZXZlbCA9IG1ldGVyLmdldFZhbHVlKCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEQ01ldGVyIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRENNZXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEQ01ldGVyXCI7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnR5cGUgPSBcIndhdmVmb3JtXCI7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSAyNTY7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgc2lnbmFsIHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWxcbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgICAgICByZXR1cm4gdmFsdWVbMF07XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RENNZXRlci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgd2F2ZWZvcm0gZGF0YSBvZiB0aGUgY29ubmVjdGVkIGF1ZGlvIHNvdXJjZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFdhdmVmb3JtIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZWZvcm0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiV2F2ZWZvcm1cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVmb3JtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnR5cGUgPSBcIndhdmVmb3JtXCI7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgd2F2ZWZvcm0gZm9yIHRoZSBjdXJyZW50IHRpbWUgYXMgYSBGbG9hdDMyQXJyYXkgd2hlcmUgZWFjaCB2YWx1ZSBpbiB0aGUgYXJyYXlcbiAgICAgKiByZXByZXNlbnRzIGEgc2FtcGxlIGluIHRoZSB3YXZlZm9ybS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqIERldGVybWluZXMgdGhlIHNpemUgb2YgdGhlIGFycmF5IHJldHVybmVkIGJ5IFtbZ2V0VmFsdWVdXS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNpemU7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IHNpemU7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V2F2ZWZvcm0uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIFNvbG8gbGV0cyB5b3UgaXNvbGF0ZSBhIHNwZWNpZmljIGF1ZGlvIHN0cmVhbS4gV2hlbiBhbiBpbnN0YW5jZSBpcyBzZXQgdG8gYHNvbG89dHJ1ZWAsXG4gKiBpdCB3aWxsIG11dGUgYWxsIG90aGVyIGluc3RhbmNlcyBvZiBTb2xvLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNvbG9BID0gbmV3IFRvbmUuU29sbygpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zY0EgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKFwiQzRcIiwgXCJzYXd0b290aFwiKS5jb25uZWN0KHNvbG9BKTtcbiAqIGNvbnN0IHNvbG9CID0gbmV3IFRvbmUuU29sbygpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zY0IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKFwiRTRcIiwgXCJzcXVhcmVcIikuY29ubmVjdChzb2xvQik7XG4gKiBzb2xvQS5zb2xvID0gdHJ1ZTtcbiAqIC8vIG5vIGF1ZGlvIHdpbGwgcGFzcyB0aHJvdWdoIHNvbG9CXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTb2xvIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNvbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzb2xvXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU29sb1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU29sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNvbG9cIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIVNvbG8uX2FsbFNvbG9zLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9hbGxTb2xvcy5zZXQodGhpcy5jb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmFkZCh0aGlzKTtcbiAgICAgICAgLy8gc2V0IGluaXRpYWxseVxuICAgICAgICB0aGlzLnNvbG8gPSBvcHRpb25zLnNvbG87XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzb2xvOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElzb2xhdGVzIHRoaXMgaW5zdGFuY2UgYW5kIG11dGVzIGFsbCBvdGhlciBpbnN0YW5jZXMgb2YgU29sby5cbiAgICAgKiBPbmx5IG9uZSBpbnN0YW5jZSBjYW4gYmUgc29sb2VkIGF0IGEgdGltZS4gQSBzb2xvZWRcbiAgICAgKiBpbnN0YW5jZSB3aWxsIHJlcG9ydCBgc29sbz1mYWxzZWAgd2hlbiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZC5cbiAgICAgKi9cbiAgICBnZXQgc29sbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzU29sb2VkKCk7XG4gICAgfVxuICAgIHNldCBzb2xvKHNvbG8pIHtcbiAgICAgICAgaWYgKHNvbG8pIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZFNvbG8oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZVNvbG8oKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9hbGxTb2xvcy5nZXQodGhpcy5jb250ZXh0KS5mb3JFYWNoKGluc3RhbmNlID0+IGluc3RhbmNlLl91cGRhdGVTb2xvKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY3VycmVudCBpbnN0YW5jZSBpcyBtdXRlZCwgaS5lLiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZFxuICAgICAqL1xuICAgIGdldCBtdXRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9PT0gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIHRoaXMgdG8gdGhlIHNvbG9lZCBhcnJheVxuICAgICAqL1xuICAgIF9hZGRTb2xvKCkge1xuICAgICAgICBpZiAoIVNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fc29sb2VkLnNldCh0aGlzLmNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmFkZCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoaXMgZnJvbSB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX3JlbW92ZVNvbG8oKSB7XG4gICAgICAgIGlmIChTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5kZWxldGUodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSXMgdGhpcyBvbiB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX2lzU29sb2VkKCkge1xuICAgICAgICByZXR1cm4gU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpICYmIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5oYXModGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBubyBvbmUgaXMgc29sb2VkXG4gICAgICovXG4gICAgX25vU29sb3MoKSB7XG4gICAgICAgIC8vIGVpdGhlciBkb2VzIG5vdCBoYXZlIGFueSBzb2xvZWQgYWRkZWRcbiAgICAgICAgcmV0dXJuICFTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgfHxcbiAgICAgICAgICAgIC8vIG9yIGhhcyBhIHNvbG8gc2V0IGJ1dCBkb2Vzbid0IGluY2x1ZGUgYW55IGl0ZW1zXG4gICAgICAgICAgICAoU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpICYmIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5zaXplID09PSAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU29sbyB0aGUgY3VycmVudCBpbnN0YW5jZSBhbmQgdW5zb2xvIGFsbCBvdGhlciBpbnN0YW5jZXMuXG4gICAgICovXG4gICAgX3VwZGF0ZVNvbG8oKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1NvbG9lZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX25vU29sb3MoKSkge1xuICAgICAgICAgICAgLy8gbm8gb25lIGlzIHNvbG9lZFxuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBTb2xvLl9hbGxTb2xvcy5nZXQodGhpcy5jb250ZXh0KS5kZWxldGUodGhpcyk7XG4gICAgICAgIHRoaXMuX3JlbW92ZVNvbG8oKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBIb2xkIGFsbCBvZiB0aGUgc29sbydlZCB0cmFja3MgYmVsb25naW5nIHRvIGEgc3BlY2lmaWMgY29udGV4dFxuICovXG5Tb2xvLl9hbGxTb2xvcyA9IG5ldyBNYXAoKTtcbi8qKlxuICogSG9sZCB0aGUgY3VycmVudGx5IHNvbG8nZWQgaW5zdGFuY2UocylcbiAqL1xuU29sby5fc29sb2VkID0gbmV3IE1hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U29sby5qcy5tYXAiLCJpbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBhbm5lciB9IGZyb20gXCIuL1Bhbm5lclwiO1xuaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4vVm9sdW1lXCI7XG4vKipcbiAqIFBhblZvbCBpcyBhIFRvbmUuUGFubmVyIGFuZCBUb25lLlZvbHVtZSBpbiBvbmUuXG4gKiBAZXhhbXBsZVxuICogLy8gcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lXG4gKiBjb25zdCBwYW5Wb2wgPSBuZXcgVG9uZS5QYW5Wb2woLTAuMjUsIC0xMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QocGFuVm9sKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFuVm9sIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhblZvbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhblwiLCBcInZvbHVtZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhblZvbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFuVm9sLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IG5ldyBQYW5uZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFuOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhbiA9IHRoaXMuX3Bhbm5lci5wYW47XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29ubmVjdCh0aGlzLl92b2x1bWUpO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInBhblwiLCBcInZvbHVtZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUvdW5tdXRlIHRoZSB2b2x1bWVcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBhbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFuVm9sLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU29sbyB9IGZyb20gXCIuL1NvbG9cIjtcbmltcG9ydCB7IFBhblZvbCB9IGZyb20gXCIuL1BhblZvbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBDaGFubmVsIHByb3ZpZGVzIGEgY2hhbm5lbCBzdHJpcCBpbnRlcmZhY2Ugd2l0aCB2b2x1bWUsIHBhbiwgc29sbyBhbmQgbXV0ZSBjb250cm9scy5cbiAqIFNlZSBbW1BhblZvbF1dIGFuZCBbW1NvbG9dXVxuICogQGV4YW1wbGVcbiAqIC8vIHBhbiB0aGUgaW5jb21pbmcgc2lnbmFsIGxlZnQgYW5kIGRyb3AgdGhlIHZvbHVtZSAxMmRiXG4gKiBjb25zdCBjaGFubmVsID0gbmV3IFRvbmUuQ2hhbm5lbCgtMC4yNSwgLTEyKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENoYW5uZWwgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hhbm5lbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiLCBcInBhblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNoYW5uZWxcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENoYW5uZWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIiwgXCJwYW5cIl0pO1xuICAgICAgICB0aGlzLl9zb2xvID0gdGhpcy5pbnB1dCA9IG5ldyBTb2xvKHtcbiAgICAgICAgICAgIHNvbG86IG9wdGlvbnMuc29sbyxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BhblZvbCA9IHRoaXMub3V0cHV0ID0gbmV3IFBhblZvbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYW46IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgICAgIG11dGU6IG9wdGlvbnMubXV0ZSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFuID0gdGhpcy5fcGFuVm9sLnBhbjtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl9wYW5Wb2wudm9sdW1lO1xuICAgICAgICB0aGlzLl9zb2xvLmNvbm5lY3QodGhpcy5fcGFuVm9sKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgc29sbzogZmFsc2UsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTb2xvL3Vuc29sbyB0aGUgY2hhbm5lbC4gU29sb2luZyBpcyBvbmx5IHJlbGF0aXZlIHRvIG90aGVyIFtbQ2hhbm5lbHNdXSBhbmQgW1tTb2xvXV0gaW5zdGFuY2VzXG4gICAgICovXG4gICAgZ2V0IHNvbG8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb2xvLnNvbG87XG4gICAgfVxuICAgIHNldCBzb2xvKHNvbG8pIHtcbiAgICAgICAgdGhpcy5fc29sby5zb2xvID0gc29sbztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGN1cnJlbnQgaW5zdGFuY2UgaXMgbXV0ZWQsIGkuZS4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWQsXG4gICAgICogb3IgdGhlIGNoYW5uZWwgaXMgbXV0ZWRcbiAgICAgKi9cbiAgICBnZXQgbXV0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb2xvLm11dGVkIHx8IHRoaXMubXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZS91bm11dGUgdGhlIHZvbHVtZVxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFuVm9sLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fcGFuVm9sLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGdhaW4gbm9kZSBiZWxvbmdpbmcgdG8gdGhlIGJ1cyBuYW1lLiBDcmVhdGUgaXQgaWZcbiAgICAgKiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGJ1cyBuYW1lXG4gICAgICovXG4gICAgX2dldEJ1cyhuYW1lKSB7XG4gICAgICAgIGlmICghQ2hhbm5lbC5idXNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIENoYW5uZWwuYnVzZXMuc2V0KG5hbWUsIG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ2hhbm5lbC5idXNlcy5nZXQobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlbmQgYXVkaW8gdG8gYW5vdGhlciBjaGFubmVsIHVzaW5nIGEgc3RyaW5nLiBgc2VuZGAgaXMgYSBsb3QgbGlrZVxuICAgICAqIFtbY29ubmVjdF1dLCBleGNlcHQgaXQgdXNlcyBhIHN0cmluZyBpbnN0ZWFkIG9mIGFuIG9iamVjdC4gVGhpcyBjYW5cbiAgICAgKiBiZSB1c2VmdWwgaW4gbGFyZ2UgYXBwbGljYXRpb25zIHRvIGRlY291cGxlIHNlY3Rpb25zIHNpbmNlIFtbc2VuZF1dXG4gICAgICogYW5kIFtbcmVjZWl2ZV1dIGNhbiBiZSBpbnZva2VkIHNlcGFyYXRlbHkgaW4gb3JkZXIgdG8gY29ubmVjdCBhbiBvYmplY3RcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgY2hhbm5lbCBuYW1lIHRvIHNlbmQgdGhlIGF1ZGlvXG4gICAgICogQHBhcmFtIHZvbHVtZSBUaGUgYW1vdW50IG9mIHRoZSBzaWduYWwgdG8gc2VuZC5cbiAgICAgKiBcdERlZmF1bHRzIHRvIDBkYiwgaS5lLiBzZW5kIHRoZSBlbnRpcmUgc2lnbmFsXG4gICAgICogQHJldHVybnMgUmV0dXJucyB0aGUgZ2FpbiBub2RlIG9mIHRoaXMgY29ubmVjdGlvbi5cbiAgICAgKi9cbiAgICBzZW5kKG5hbWUsIHZvbHVtZSA9IDApIHtcbiAgICAgICAgY29uc3QgYnVzID0gdGhpcy5fZ2V0QnVzKG5hbWUpO1xuICAgICAgICBjb25zdCBzZW5kS25vYiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBnYWluOiB2b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbm5lY3Qoc2VuZEtub2IpO1xuICAgICAgICBzZW5kS25vYi5jb25uZWN0KGJ1cyk7XG4gICAgICAgIHJldHVybiBzZW5kS25vYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVjZWl2ZSBhdWRpbyBmcm9tIGEgY2hhbm5lbCB3aGljaCB3YXMgY29ubmVjdGVkIHdpdGggW1tzZW5kXV0uXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGNoYW5uZWwgbmFtZSB0byByZWNlaXZlIGF1ZGlvIGZyb20uXG4gICAgICovXG4gICAgcmVjZWl2ZShuYW1lKSB7XG4gICAgICAgIGNvbnN0IGJ1cyA9IHRoaXMuX2dldEJ1cyhuYW1lKTtcbiAgICAgICAgYnVzLmNvbm5lY3QodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhblZvbC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zb2xvLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBTdG9yZSB0aGUgc2VuZC9yZWNlaXZlIGNoYW5uZWxzIGJ5IG5hbWUuXG4gKi9cbkNoYW5uZWwuYnVzZXMgPSBuZXcgTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaGFubmVsLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi9NZXJnZVwiO1xuLyoqXG4gKiBNb25vIGNvZXJjZXMgdGhlIGluY29taW5nIG1vbm8gb3Igc3RlcmVvIHNpZ25hbCBpbnRvIGEgbW9ubyBzaWduYWxcbiAqIHdoZXJlIGJvdGggbGVmdCBhbmQgcmlnaHQgY2hhbm5lbHMgaGF2ZSB0aGUgc2FtZSB2YWx1ZS4gVGhpcyBjYW4gYmUgdXNlZnVsXG4gKiBmb3IgW3N0ZXJlbyBpbWFnaW5nXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGVyZW9faW1hZ2luZykuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNb25vIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTW9ub1wiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWVyZ2Uoe1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vbm8uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9maWx0ZXIvRmlsdGVyXCI7XG4vKipcbiAqIFNwbGl0IHRoZSBpbmNvbWluZyBzaWduYWwgaW50byB0aHJlZSBiYW5kcyAobG93LCBtaWQsIGhpZ2gpXG4gKiB3aXRoIHR3byBjcm9zc292ZXIgZnJlcXVlbmN5IGNvbnRyb2xzLlxuICogYGBgXG4gKiAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgKy0+IGlucHV0IDwgbG93RnJlcXVlbmN5ICstLS0tLS0tLS0tLS0tLS0tLS0+IGxvd1xuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgIHxcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogaW5wdXQgLS0tKy0+IGxvd0ZyZXF1ZW5jeSA8IGlucHV0IDwgaGlnaEZyZXF1ZW5jeSArLS0+IG1pZFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICB8XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICstPiBoaWdoRnJlcXVlbmN5IDwgaW5wdXQgKy0tLS0tLS0tLS0tLS0tLS0tPiBoaWdoXG4gKiAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGliYW5kU3BsaXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGliYW5kU3BsaXRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogbm8gb3V0cHV0IG5vZGUsIHVzZSBlaXRoZXIgbG93LCBtaWQgb3IgaGlnaCBvdXRwdXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb3cgYmFuZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubG93ID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbG93ZXIgZmlsdGVyIG9mIHRoZSBtaWQgYmFuZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG93TWlkRmlsdGVyID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1pZCBiYW5kIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubWlkID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaGlnaCBiYW5kIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGlnaCA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmxvdywgdGhpcy5taWQsIHRoaXMuaGlnaF07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLmxvdywgdGhpcy5oaWdoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9sb3dNaWRGaWx0ZXIsIHRoaXMubWlkKTtcbiAgICAgICAgLy8gdGhlIGZyZXF1ZW5jeSBjb250cm9sIHNpZ25hbFxuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5mYW4odGhpcy5sb3cuZnJlcXVlbmN5LCB0aGlzLl9sb3dNaWRGaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmZhbih0aGlzLm1pZC5mcmVxdWVuY3ksIHRoaXMuaGlnaC5mcmVxdWVuY3kpO1xuICAgICAgICAvLyB0aGUgUSB2YWx1ZVxuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmxvdy5RKTtcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5fbG93TWlkRmlsdGVyLlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLm1pZC5RKTtcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5oaWdoLlEpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJoaWdoXCIsIFwibWlkXCIsIFwibG93XCIsIFwiaGlnaEZyZXF1ZW5jeVwiLCBcImxvd0ZyZXF1ZW5jeVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogMjUwMCxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogNDAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJoaWdoXCIsIFwibWlkXCIsIFwibG93XCIsIFwiaGlnaEZyZXF1ZW5jeVwiLCBcImxvd0ZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93TWlkRmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU11bHRpYmFuZFNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuL1BhcmFtXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuL0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuLyoqXG4gKiBUb25lLkxpc3RlbmVyIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgQXVkaW9MaXN0ZW5lci4gTGlzdGVuZXIgY29tYmluZWRcbiAqIHdpdGggW1tQYW5uZXIzRF1dIG1ha2VzIHVwIHRoZSBXZWIgQXVkaW8gQVBJJ3MgM0QgcGFubmluZyBzeXN0ZW0uIFBhbm5lcjNEIGFsbG93cyB5b3VcbiAqIHRvIHBsYWNlIHNvdW5kcyBpbiAzRCBhbmQgTGlzdGVuZXIgYWxsb3dzIHlvdSB0byBuYXZpZ2F0ZSB0aGUgM0Qgc291bmQgZW52aXJvbm1lbnQgZnJvbVxuICogYSBmaXJzdC1wZXJzb24gcGVyc3BlY3RpdmUuIFRoZXJlIGlzIG9ubHkgb25lIGxpc3RlbmVyIHBlciBhdWRpbyBjb250ZXh0LlxuICovXG5leHBvcnQgY2xhc3MgTGlzdGVuZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMaXN0ZW5lclwiO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRYID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBYLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBaID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFosXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcG9zaXRpb25YOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25ZOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25aOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFg6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWTogMCxcbiAgICAgICAgICAgIGZvcndhcmRaOiAtMSxcbiAgICAgICAgICAgIHVwWDogMCxcbiAgICAgICAgICAgIHVwWTogMSxcbiAgICAgICAgICAgIHVwWjogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRaLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBaLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5saXN0ZW5lciA9IG5ldyBMaXN0ZW5lcih7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQubGlzdGVuZXIuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MaXN0ZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IFwiLi4vLi4vY29yZS9jb250ZXh0L0xpc3RlbmVyXCI7XG4vKipcbiAqIEEgc3BhdGlhbGl6ZWQgcGFubmVyIG5vZGUgd2hpY2ggc3VwcG9ydHMgZXF1YWxwb3dlciBvciBIUlRGIHBhbm5pbmcuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5uZXIzRCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIzRC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBvc2l0aW9uWFwiLCBcInBvc2l0aW9uWVwiLCBcInBvc2l0aW9uWlwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhbm5lcjNEXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIzRC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBvc2l0aW9uWFwiLCBcInBvc2l0aW9uWVwiLCBcInBvc2l0aW9uWlwiXSk7XG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gc2V0IHNvbWUgdmFsdWVzXG4gICAgICAgIHRoaXMucGFubmluZ01vZGVsID0gb3B0aW9ucy5wYW5uaW5nTW9kZWw7XG4gICAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSBvcHRpb25zLm1heERpc3RhbmNlO1xuICAgICAgICB0aGlzLmRpc3RhbmNlTW9kZWwgPSBvcHRpb25zLmRpc3RhbmNlTW9kZWw7XG4gICAgICAgIHRoaXMuY29uZU91dGVyR2FpbiA9IG9wdGlvbnMuY29uZU91dGVyR2FpbjtcbiAgICAgICAgdGhpcy5jb25lT3V0ZXJBbmdsZSA9IG9wdGlvbnMuY29uZU91dGVyQW5nbGU7XG4gICAgICAgIHRoaXMuY29uZUlubmVyQW5nbGUgPSBvcHRpb25zLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB0aGlzLnJlZkRpc3RhbmNlID0gb3B0aW9ucy5yZWZEaXN0YW5jZTtcbiAgICAgICAgdGhpcy5yb2xsb2ZmRmFjdG9yID0gb3B0aW9ucy5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25ZLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblosXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25ZLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblosXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblosXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29uZUlubmVyQW5nbGU6IDM2MCxcbiAgICAgICAgICAgIGNvbmVPdXRlckFuZ2xlOiAzNjAsXG4gICAgICAgICAgICBjb25lT3V0ZXJHYWluOiAwLFxuICAgICAgICAgICAgZGlzdGFuY2VNb2RlbDogXCJpbnZlcnNlXCIsXG4gICAgICAgICAgICBtYXhEaXN0YW5jZTogMTAwMDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblg6IDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblk6IDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblo6IDAsXG4gICAgICAgICAgICBwYW5uaW5nTW9kZWw6IFwiZXF1YWxwb3dlclwiLFxuICAgICAgICAgICAgcG9zaXRpb25YOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25ZOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25aOiAwLFxuICAgICAgICAgICAgcmVmRGlzdGFuY2U6IDEsXG4gICAgICAgICAgICByb2xsb2ZmRmFjdG9yOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcG9zaXRpb24gb2YgdGhlIHNvdXJjZSBpbiAzZCBzcGFjZS5cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbih4LCB5LCB6KSB7XG4gICAgICAgIHRoaXMucG9zaXRpb25YLnZhbHVlID0geDtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkudmFsdWUgPSB5O1xuICAgICAgICB0aGlzLnBvc2l0aW9uWi52YWx1ZSA9IHo7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuICAgICAqL1xuICAgIHNldE9yaWVudGF0aW9uKHgsIHksIHopIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblgudmFsdWUgPSB4O1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWS52YWx1ZSA9IHk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25aLnZhbHVlID0gejtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYW5uaW5nIG1vZGVsLiBFaXRoZXIgXCJlcXVhbHBvd2VyXCIgb3IgXCJIUlRGXCIuXG4gICAgICovXG4gICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5wYW5uaW5nTW9kZWw7XG4gICAgfVxuICAgIHNldCBwYW5uaW5nTW9kZWwodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5wYW5uaW5nTW9kZWwgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVmZXJlbmNlIGRpc3RhbmNlIGZvciByZWR1Y2luZyB2b2x1bWUgYXMgc291cmNlIG1vdmUgZnVydGhlciBmcm9tIHRoZSBsaXN0ZW5lclxuICAgICAqL1xuICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZTtcbiAgICB9XG4gICAgc2V0IHJlZkRpc3RhbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucmVmRGlzdGFuY2UgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlc2NyaWJlcyBob3cgcXVpY2tseSB0aGUgdm9sdW1lIGlzIHJlZHVjZWQgYXMgc291cmNlIG1vdmVzIGF3YXkgZnJvbSBsaXN0ZW5lci5cbiAgICAgKi9cbiAgICBnZXQgcm9sbG9mZkZhY3RvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5yb2xsb2ZmRmFjdG9yO1xuICAgIH1cbiAgICBzZXQgcm9sbG9mZkZhY3Rvcih2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3IgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkaXN0YW5jZSBtb2RlbCB1c2VkIGJ5LCAgXCJsaW5lYXJcIiwgXCJpbnZlcnNlXCIsIG9yIFwiZXhwb25lbnRpYWxcIi5cbiAgICAgKi9cbiAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5kaXN0YW5jZU1vZGVsO1xuICAgIH1cbiAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWwgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmdsZSwgaW4gZGVncmVlcywgaW5zaWRlIG9mIHdoaWNoIHRoZXJlIHdpbGwgYmUgbm8gdm9sdW1lIHJlZHVjdGlvblxuICAgICAqL1xuICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lSW5uZXJBbmdsZTtcbiAgICB9XG4gICAgc2V0IGNvbmVJbm5lckFuZ2xlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29uZUlubmVyQW5nbGUgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmdsZSwgaW4gZGVncmVlcywgb3V0c2lkZSBvZiB3aGljaCB0aGUgdm9sdW1lIHdpbGwgYmUgcmVkdWNlZFxuICAgICAqIHRvIGEgY29uc3RhbnQgdmFsdWUgb2YgY29uZU91dGVyR2FpblxuICAgICAqL1xuICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJBbmdsZTtcbiAgICB9XG4gICAgc2V0IGNvbmVPdXRlckFuZ2xlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29uZU91dGVyQW5nbGUgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBnYWluIG91dHNpZGUgb2YgdGhlIGNvbmVPdXRlckFuZ2xlXG4gICAgICovXG4gICAgZ2V0IGNvbmVPdXRlckdhaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIuY29uZU91dGVyR2FpbjtcbiAgICB9XG4gICAgc2V0IGNvbmVPdXRlckdhaW4odmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJHYWluID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBkaXN0YW5jZSBiZXR3ZWVuIHNvdXJjZSBhbmQgbGlzdGVuZXIsXG4gICAgICogYWZ0ZXIgd2hpY2ggdGhlIHZvbHVtZSB3aWxsIG5vdCBiZSByZWR1Y2VkIGFueSBmdXJ0aGVyLlxuICAgICAqL1xuICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZTtcbiAgICB9XG4gICAgc2V0IG1heERpc3RhbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIubWF4RGlzdGFuY2UgPSB2YWw7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFubmVyM0QuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyB0aGVXaW5kb3cgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIEEgd3JhcHBlciBhcm91bmQgdGhlIE1lZGlhUmVjb3JkZXIgQVBJLiBVbmxpa2UgdGhlIHJlc3Qgb2YgVG9uZS5qcywgdGhpcyBtb2R1bGUgZG9lcyBub3Qgb2ZmZXJcbiAqIGFueSBzYW1wbGUtYWNjdXJhdGUgc2NoZWR1bGluZyBiZWNhdXNlIGl0IGlzIG5vdCBhIGZlYXR1cmUgb2YgdGhlIE1lZGlhUmVjb3JkZXIgQVBJLlxuICogVGhpcyBpcyBvbmx5IG5hdGl2ZWx5IHN1cHBvcnRlZCBpbiBDaHJvbWUgYW5kIEZpcmVmb3guXG4gKiBGb3IgYSBjcm9zcy1icm93c2VyIHNoaW0sIGluc3RhbGwgKGF1ZGlvLXJlY29yZGVyLXBvbHlmaWxsKVtodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hdWRpby1yZWNvcmRlci1wb2x5ZmlsbF0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcmVjb3JkZXIgPSBuZXcgVG9uZS5SZWNvcmRlcigpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QocmVjb3JkZXIpO1xuICogLy8gc3RhcnQgcmVjb3JkaW5nXG4gKiByZWNvcmRlci5zdGFydCgpO1xuICogLy8gZ2VuZXJhdGUgYSBmZXcgbm90ZXNcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzNcIiwgMC41KTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgMC41LCBcIisxXCIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNVwiLCAwLjUsIFwiKzJcIik7XG4gKiAvLyB3YWl0IGZvciB0aGUgbm90ZXMgdG8gZW5kIGFuZCBzdG9wIHRoZSByZWNvcmRpbmdcbiAqIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICogXHQvLyB0aGUgcmVjb3JkZWQgYXVkaW8gaXMgcmV0dXJuZWQgYXMgYSBibG9iXG4gKiBcdGNvbnN0IHJlY29yZGluZyA9IGF3YWl0IHJlY29yZGVyLnN0b3AoKTtcbiAqIFx0Ly8gZG93bmxvYWQgdGhlIHJlY29yZGluZyBieSBjcmVhdGluZyBhbiBhbmNob3IgZWxlbWVudCBhbmQgYmxvYiB1cmxcbiAqIFx0Y29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChyZWNvcmRpbmcpO1xuICogXHRjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAqIFx0YW5jaG9yLmRvd25sb2FkID0gXCJyZWNvcmRpbmcud2VibVwiO1xuICogXHRhbmNob3IuaHJlZiA9IHVybDtcbiAqIFx0YW5jaG9yLmNsaWNrKCk7XG4gKiB9LCA0MDAwKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlY29yZGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFJlY29yZGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJlY29yZGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhSZWNvcmRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQoUmVjb3JkZXIuc3VwcG9ydGVkLCBcIk1lZGlhIFJlY29yZGVyIEFQSSBpcyBub3QgYXZhaWxhYmxlXCIpO1xuICAgICAgICB0aGlzLl9zdHJlYW0gPSB0aGlzLmNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3RyZWFtKTtcbiAgICAgICAgdGhpcy5fcmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcih0aGlzLl9zdHJlYW0uc3RyZWFtLCB7XG4gICAgICAgICAgICBtaW1lVHlwZTogb3B0aW9ucy5taW1lVHlwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWltZSB0eXBlIGlzIHRoZSBmb3JtYXQgdGhhdCB0aGUgYXVkaW8gaXMgZW5jb2RlZCBpbi4gRm9yIENocm9tZVxuICAgICAqIHRoYXQgaXMgdHlwaWNhbGx5IHdlYm0gZW5jb2RlZCBhcyBcInZvcmJpc1wiLlxuICAgICAqL1xuICAgIGdldCBtaW1lVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlY29yZGVyLm1pbWVUeXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUZXN0IGlmIHlvdXIgcGxhdGZvcm0gc3VwcG9ydHMgdGhlIE1lZGlhIFJlY29yZGVyIEFQSS4gSWYgaXQncyBub3QgYXZhaWxhYmxlLFxuICAgICAqIHRyeSBpbnN0YWxsaW5nIHRoaXMgKHBvbHlmaWxsKVtodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hdWRpby1yZWNvcmRlci1wb2x5ZmlsbF0uXG4gICAgICovXG4gICAgc3RhdGljIGdldCBzdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGVXaW5kb3cgIT09IG51bGwgJiYgUmVmbGVjdC5oYXModGhlV2luZG93LCBcIk1lZGlhUmVjb3JkZXJcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIFJlY29yZGVyLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCJcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9yZWNvcmRlci5zdGF0ZSA9PT0gXCJpbmFjdGl2ZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVjb3JkZXIuc3RhdGUgPT09IFwicGF1c2VkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBcInBhdXNlZFwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFwic3RhcnRlZFwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBSZWNvcmRlci4gUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXNcbiAgICAgKiB3aGVuIHRoZSByZWNvcmRlciBoYXMgc3RhcnRlZC5cbiAgICAgKi9cbiAgICBzdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnN0YXRlICE9PSBcInN0YXJ0ZWRcIiwgXCJSZWNvcmRlciBpcyBhbHJlYWR5IHN0YXJ0ZWRcIik7XG4gICAgICAgICAgICBjb25zdCBzdGFydFByb21pc2UgPSBuZXcgUHJvbWlzZShkb25lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVTdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInN0YXJ0XCIsIGhhbmRsZVN0YXJ0LCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJzdGFydFwiLCBoYW5kbGVTdGFydCwgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5zdGFydCgpO1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIHN0YXJ0UHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHJlY29yZGVyLiBSZXR1cm5zIGEgcHJvbWlzZSB3aXRoIHRoZSByZWNvcmRlZCBjb250ZW50IHVudGlsIHRoaXMgcG9pbnRcbiAgICAgKiBlbmNvZGVkIGFzIFtbbWltZVR5cGVdXVxuICAgICAqL1xuICAgIHN0b3AoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5zdGF0ZSAhPT0gXCJzdG9wcGVkXCIsIFwiUmVjb3JkZXIgaXMgbm90IHN0YXJ0ZWRcIik7XG4gICAgICAgICAgICBjb25zdCBkYXRhUHJvbWlzZSA9IG5ldyBQcm9taXNlKGRvbmUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZURhdGEgPSAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZGF0YWF2YWlsYWJsZVwiLCBoYW5kbGVEYXRhLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZS5kYXRhKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJkYXRhYXZhaWxhYmxlXCIsIGhhbmRsZURhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuc3RvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIGRhdGFQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIHJlY29yZGVyXG4gICAgICovXG4gICAgcGF1c2UoKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIiwgXCJSZWNvcmRlciBtdXN0IGJlIHN0YXJ0ZWRcIik7XG4gICAgICAgIHRoaXMuX3JlY29yZGVyLnBhdXNlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdHJlYW0uZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1SZWNvcmRlci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBDb21wcmVzc29yIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgV2ViIEF1ZGlvXG4gKiBbRHluYW1pY3NDb21wcmVzc29yTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtZHluYW1pY3Njb21wcmVzc29ybm9kZS1pbnRlcmZhY2UpLlxuICogQ29tcHJlc3Npb24gcmVkdWNlcyB0aGUgdm9sdW1lIG9mIGxvdWQgc291bmRzIG9yIGFtcGxpZmllcyBxdWlldCBzb3VuZHNcbiAqIGJ5IG5hcnJvd2luZyBvciBcImNvbXByZXNzaW5nXCIgYW4gYXVkaW8gc2lnbmFsJ3MgZHluYW1pYyByYW5nZS5cbiAqIFJlYWQgbW9yZSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EeW5hbWljX3JhbmdlX2NvbXByZXNzaW9uKS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjb21wID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMzAsIDMpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ29tcHJlc3NvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwicmF0aW9cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb21wcmVzc29yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgY29tcHJlc3NvciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yID0gdGhpcy5jb250ZXh0LmNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fY29tcHJlc3NvcjtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9jb21wcmVzc29yO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInJhdGlvXCJdKTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuYXR0YWNrLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJlbGVhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmtuZWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3Iua25lZS5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLmtuZWUubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLmtuZWUsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMua25lZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmF0aW8gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmF0aW8ubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yYXRpby5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IucmF0aW8sXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmF0aW8sXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzZXQgdGhlIGRlZmF1bHRzXG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImtuZWVcIiwgXCJyZWxlYXNlXCIsIFwiYXR0YWNrXCIsIFwicmF0aW9cIiwgXCJ0aHJlc2hvbGRcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLjAwMyxcbiAgICAgICAgICAgIGtuZWU6IDMwLFxuICAgICAgICAgICAgcmF0aW86IDEyLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWFkLW9ubHkgZGVjaWJlbCB2YWx1ZSBmb3IgbWV0ZXJpbmcgcHVycG9zZXMsIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBhbW91bnQgb2YgZ2FpblxuICAgICAqIHJlZHVjdGlvbiB0aGF0IHRoZSBjb21wcmVzc29yIGlzIGFwcGx5aW5nIHRvIHRoZSBzaWduYWwuIElmIGZlZCBubyBzaWduYWwgdGhlIHZhbHVlIHdpbGwgYmUgMCAobm8gZ2FpbiByZWR1Y3Rpb24pLlxuICAgICAqL1xuICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb21wcmVzc29yLnJlZHVjdGlvbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5hdHRhY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnJlbGVhc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRocmVzaG9sZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmF0aW8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmtuZWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9HcmVhdGVyVGhhblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgRm9sbG93ZXIgfSBmcm9tIFwiLi4vYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuLyoqXG4gKiBHYXRlIG9ubHkgcGFzc2VzIGEgc2lnbmFsIHRocm91Z2ggd2hlbiB0aGUgaW5jb21pbmdcbiAqIHNpZ25hbCBleGNlZWRzIGEgc3BlY2lmaWVkIHRocmVzaG9sZC4gSXQgdXNlcyBbW0ZvbGxvd2VyXV0gdG8gZm9sbG93IHRoZSBhbXBsdGl1ZGVcbiAqIG9mIHRoZSBpbmNvbWluZyBzaWduYWwgYW5kIGNvbXBhcmVzIGl0IHRvIHRoZSBbW3RocmVzaG9sZF1dIHZhbHVlIHVzaW5nIFtbR3JlYXRlclRoYW5dXS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZ2F0ZSA9IG5ldyBUb25lLkdhdGUoLTMwLCAwLjIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLmNvbm5lY3QoZ2F0ZSk7XG4gKiAvLyB0aGUgZ2F0ZSB3aWxsIG9ubHkgcGFzcyB0aHJvdWdoIHRoZSBpbmNvbWluZ1xuICogLy8gc2lnbmFsIHdoZW4gaXQncyBsb3VkZXIgdGhhbiAtMzBkYlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgR2F0ZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhdGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJzbW9vdGhpbmdcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR2F0ZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR2F0ZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInNtb290aGluZ1wiXSk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyID0gbmV3IEZvbGxvd2VyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHNtb290aGluZzogb3B0aW9ucy5zbW9vdGhpbmcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ndCA9IG5ldyBHcmVhdGVyVGhhbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogZGJUb0dhaW4ob3B0aW9ucy50aHJlc2hvbGQpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9nYXRlID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX2dhdGUpO1xuICAgICAgICAvLyB0aGUgY29udHJvbCBzaWduYWxcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9mb2xsb3dlciwgdGhpcy5fZ3QsIHRoaXMuX2dhdGUuZ2Fpbik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuMSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogLTQwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGhyZXNob2xkIG9mIHRoZSBnYXRlIGluIGRlY2liZWxzXG4gICAgICovXG4gICAgZ2V0IHRocmVzaG9sZCgpIHtcbiAgICAgICAgcmV0dXJuIGdhaW5Ub0RiKHRoaXMuX2d0LnZhbHVlKTtcbiAgICB9XG4gICAgc2V0IHRocmVzaG9sZCh0aHJlc2gpIHtcbiAgICAgICAgdGhpcy5fZ3QudmFsdWUgPSBkYlRvR2Fpbih0aHJlc2gpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXR0YWNrL2RlY2F5IHNwZWVkIG9mIHRoZSBnYXRlLiBTZWUgW1tGb2xsb3dlci5zbW9vdGhpbmddXVxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcoc21vb3RoaW5nVGltZSkge1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmcgPSBzbW9vdGhpbmdUaW1lO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2d0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdhdGUuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBDb21wcmVzc29yIH0gZnJvbSBcIi4vQ29tcHJlc3NvclwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuO1xuLyoqXG4gKiBMaW1pdGVyIHdpbGwgbGltaXQgdGhlIGxvdWRuZXNzIG9mIGFuIGluY29taW5nIHNpZ25hbC5cbiAqIFVuZGVyIHRoZSBob29kIGl0J3MgY29tcG9zZWQgb2YgYSBbW0NvbXByZXNzb3JdXSB3aXRoIGEgZmFzdCBhdHRhY2tcbiAqIGFuZCByZWxlYXNlIGFuZCBtYXggY29tcHJlc3Npb24gcmF0aW8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGxpbWl0ZXIgPSBuZXcgVG9uZS5MaW1pdGVyKC0yMCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGxpbWl0ZXIpO1xuICogb3NjaWxsYXRvci5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTGltaXRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKExpbWl0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTGltaXRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTGltaXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiXSk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgQ29tcHJlc3Nvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICByYXRpbzogMjAsXG4gICAgICAgICAgICBhdHRhY2s6IDAuMDAzLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4wMSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogb3B0aW9ucy50aHJlc2hvbGRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkID0gdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQ7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidGhyZXNob2xkXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdGhyZXNob2xkOiAtMTJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVhZC1vbmx5IGRlY2liZWwgdmFsdWUgZm9yIG1ldGVyaW5nIHB1cnBvc2VzLCByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgYW1vdW50IG9mIGdhaW5cbiAgICAgKiByZWR1Y3Rpb24gdGhhdCB0aGUgY29tcHJlc3NvciBpcyBhcHBseWluZyB0byB0aGUgc2lnbmFsLlxuICAgICAqL1xuICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb21wcmVzc29yLnJlZHVjdGlvbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MaW1pdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1pZFNpZGVTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL01pZFNpZGVTcGxpdFwiO1xuaW1wb3J0IHsgTWlkU2lkZU1lcmdlIH0gZnJvbSBcIi4uL2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIE1pZFNpZGVDb21wcmVzc29yIGFwcGxpZXMgdHdvIGRpZmZlcmVudCBjb21wcmVzc29ycyB0byB0aGUgW1ttaWRdXVxuICogYW5kIFtbc2lkZV1dIHNpZ25hbCBjb21wb25lbnRzIG9mIHRoZSBpbnB1dC4gU2VlIFtbTWlkU2lkZVNwbGl0XV0gYW5kIFtbTWlkU2lkZU1lcmdlXV0uXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlQ29tcHJlc3NvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlQ29tcHJlc3NvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZUNvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0ID0gdGhpcy5pbnB1dCA9IG5ldyBNaWRTaWRlU3BsaXQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1pZFNpZGVNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubWlkLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5zaWRlLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMuX21pZFNpZGVNZXJnZS5taWQpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZS5jaGFpbih0aGlzLnNpZGUsIHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibWlkXCIsIFwic2lkZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtaWQ6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNpZGU6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogNixcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0zMCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMyxcbiAgICAgICAgICAgICAgICBrbmVlOiAxMFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVDb21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpYmFuZFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbi8qKlxuICogQSBjb21wcmVzc29yIHdpdGggc2VwYXJhdGUgY29udHJvbHMgb3ZlciBsb3cvbWlkL2hpZ2ggZHluYW1pY3MuIFNlZSBbW0NvbXByZXNzb3JdXSBhbmQgW1tNdWx0aWJhbmRTcGxpdF1dXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG11bHRpYmFuZCA9IG5ldyBUb25lLk11bHRpYmFuZENvbXByZXNzb3Ioe1xuICogXHRsb3dGcmVxdWVuY3k6IDIwMCxcbiAqIFx0aGlnaEZyZXF1ZW5jeTogMTMwMCxcbiAqIFx0bG93OiB7XG4gKiBcdFx0dGhyZXNob2xkOiAtMTJcbiAqIFx0fVxuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aWJhbmRDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGliYW5kQ29tcHJlc3NvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGliYW5kU3BsaXQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSB0aGlzLl9zcGxpdHRlci5sb3dGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IHRoaXMuX3NwbGl0dGVyLmhpZ2hGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMubG93ID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLmxvdywgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5taWQsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5oaWdoID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLmhpZ2gsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY29tcHJlc3NvclxuICAgICAgICB0aGlzLl9zcGxpdHRlci5sb3cuY2hhaW4odGhpcy5sb3csIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIubWlkLmNoYWluKHRoaXMubWlkLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmhpZ2guY2hhaW4odGhpcy5oaWdoLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogMjUwLFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogMjAwMCxcbiAgICAgICAgICAgIGxvdzoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiA2LFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTMwLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAzLFxuICAgICAgICAgICAgICAgIGtuZWU6IDEwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWlkOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDMsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4wMyxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDIsXG4gICAgICAgICAgICAgICAga25lZTogMTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoaWdoOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDMsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4wMyxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDIsXG4gICAgICAgICAgICAgICAga25lZTogMTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGliYW5kQ29tcHJlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aWJhbmRTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL011bHRpYmFuZFNwbGl0XCI7XG4vKipcbiAqIEVRMyBwcm92aWRlcyAzIGVxdWFsaXplciBiaW5zOiBMb3cvTWlkL0hpZ2guXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBFUTMgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRVEzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVRM1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRVEzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdCA9IG5ldyBNdWx0aWJhbmRTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiBvcHRpb25zLmhpZ2hGcmVxdWVuY3ksXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbG93R2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMubG93LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pZEdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLm1pZCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9oaWdoR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMuaGlnaCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvdyA9IHRoaXMuX2xvd0dhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5taWQgPSB0aGlzLl9taWRHYWluLmdhaW47XG4gICAgICAgIHRoaXMuaGlnaCA9IHRoaXMuX2hpZ2hHYWluLmdhaW47XG4gICAgICAgIHRoaXMuUSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LlE7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQubG93RnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5oaWdoRnJlcXVlbmN5O1xuICAgICAgICAvLyB0aGUgZnJlcXVlbmN5IGJhbmRzXG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0Lmxvdy5jaGFpbih0aGlzLl9sb3dHYWluLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0Lm1pZC5jaGFpbih0aGlzLl9taWRHYWluLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0LmhpZ2guY2hhaW4odGhpcy5faGlnaEdhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiLCBcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX211bHRpYmFuZFNwbGl0XTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhpZ2g6IDAsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyNTAwLFxuICAgICAgICAgICAgbG93OiAwLFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiA0MDAsXG4gICAgICAgICAgICBtaWQ6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImxvd1wiLCBcIm1pZFwiLCBcImhpZ2hcIiwgXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xvd0dhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5faGlnaEdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RVEzLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENvbnZvbHZlciBpcyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBOYXRpdmUgV2ViIEF1ZGlvXG4gKiBbQ29udm9sdmVyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtY29udm9sdmVybm9kZS1pbnRlcmZhY2UpLlxuICogQ29udm9sdXRpb24gaXMgdXNlZnVsIGZvciByZXZlcmIgYW5kIGZpbHRlciBlbXVsYXRpb24uIFJlYWQgbW9yZSBhYm91dCBjb252b2x1dGlvbiByZXZlcmIgb25cbiAqIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbnZvbHV0aW9uX3JldmVyYikuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemluZyB0aGUgY29udm9sdmVyIHdpdGggYW4gaW1wdWxzZSByZXNwb25zZVxuICogY29uc3QgY29udm9sdmVyID0gbmV3IFRvbmUuQ29udm9sdmVyKFwiLi9wYXRoL3RvL2lyLndhdlwiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDb252b2x2ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udm9sdmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29udm9sdmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmF0aXZlIENvbnZvbHZlck5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnZvbHZlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIob3B0aW9ucy51cmwsIGJ1ZmZlciA9PiB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgICAgIG9wdGlvbnMub25sb2FkKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8vIHNldCBpZiBpdCdzIGFscmVhZHkgbG9hZGVkLCBzZXQgaXQgaW1tZWRpYXRlbHlcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gdGhpcy5fYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIC8vIGluaXRpYWxseSBzZXQgbm9ybWFsaXphdGlvblxuICAgICAgICB0aGlzLm5vcm1hbGl6ZSA9IG9wdGlvbnMubm9ybWFsaXplO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fY29udm9sdmVyLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBub3JtYWxpemU6IHRydWUsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkIGFuIGltcHVsc2UgcmVzcG9uc2UgdXJsIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBEZWNvZGVzIHRoZSBhdWRpbyBhc3luY2hyb25vdXNseSBhbmQgaW52b2tlc1xuICAgICAqIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gZmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHlpZWxkIHRoaXMuX2J1ZmZlci5sb2FkKHVybCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY29udm9sdmVyJ3MgYnVmZmVyXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgYnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgaXQncyBhbHJlYWR5IGdvdCBhIGJ1ZmZlciwgY3JlYXRlIGEgbmV3IG9uZVxuICAgICAgICBpZiAodGhpcy5fY29udm9sdmVyLmJ1ZmZlcikge1xuICAgICAgICAgICAgLy8gZGlzY29ubmVjdCB0aGUgb2xkIG9uZVxuICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgLy8gY3JlYXRlIGFuZCBjb25uZWN0IGEgbmV3IG9uZVxuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9jb252b2x2ZXIsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBidWZmID0gdGhpcy5fYnVmZmVyLmdldCgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuYnVmZmVyID0gYnVmZiA/IGJ1ZmYgOiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbm9ybWFsaXplIHByb3BlcnR5IG9mIHRoZSBDb252b2x2ZXJOb2RlIGludGVyZmFjZSBpcyBhIGJvb2xlYW4gdGhhdFxuICAgICAqIGNvbnRyb2xzIHdoZXRoZXIgdGhlIGltcHVsc2UgcmVzcG9uc2UgZnJvbSB0aGUgYnVmZmVyIHdpbGwgYmUgc2NhbGVkIGJ5XG4gICAgICogYW4gZXF1YWwtcG93ZXIgbm9ybWFsaXphdGlvbiB3aGVuIHRoZSBidWZmZXIgYXR0cmlidXRlIGlzIHNldCwgb3Igbm90LlxuICAgICAqL1xuICAgIGdldCBub3JtYWxpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb252b2x2ZXIubm9ybWFsaXplO1xuICAgIH1cbiAgICBzZXQgbm9ybWFsaXplKG5vcm0pIHtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLm5vcm1hbGl6ZSA9IG5vcm07XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udm9sdmVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0FuYWx5c2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9NZXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvRkZUXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9EQ01ldGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9XYXZlZm9ybVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvQ2hhbm5lbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWVyZ2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01pZFNpZGVTcGxpdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Nb25vXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL011bHRpYmFuZFNwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1Bhbm5lclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9QYW5uZXIzRFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9QYW5Wb2xcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUmVjb3JkZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvU29sb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9TcGxpdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Wb2x1bWVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0NvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0dhdGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0xpbWl0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL01pZFNpZGVDb21wcmVzc29yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9NdWx0aWJhbmRDb21wcmVzc29yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0ZyZXF1ZW5jeUVudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRVEzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvT25lUG9sZUZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvQ29udm9sdmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvQmlxdWFkRmlsdGVyXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9jb3JlL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zb3VyY2UvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NpZ25hbC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vaW5zdHJ1bWVudC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXZlbnQvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VmZmVjdC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29tcG9uZW50L2luZGV4XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jbGFzc2VzLmpzLm1hcCIsImV4cG9ydCB7IGdldENvbnRleHQsIHNldENvbnRleHQgfSBmcm9tIFwiLi9jb3JlL0dsb2JhbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2xhc3Nlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5leHBvcnQgeyBzdGFydCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5leHBvcnQgeyBzdXBwb3J0ZWQgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG4vKipcbiAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBvZiB0aGUgZ2xvYmFsIFtbQ29udGV4dF1dLlxuICogU2VlIFtbQ29udGV4dC5ub3ddXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdygpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLm5vdygpO1xufVxuLyoqXG4gKiBUaGUgY3VycmVudCBhdWRpbyBjb250ZXh0IHRpbWUgb2YgdGhlIGdsb2JhbCBbW0NvbnRleHRdXSB3aXRob3V0IHRoZSBbW0NvbnRleHQubG9va0FoZWFkXV1cbiAqIFNlZSBbW0NvbnRleHQuaW1tZWRpYXRlXV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbW1lZGlhdGUoKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5pbW1lZGlhdGUoKTtcbn1cbi8qKlxuICogVGhlIFRyYW5zcG9ydCBvYmplY3QgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbVHJhbnNwb3J0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUcmFuc3BvcnQgPSBnZXRDb250ZXh0KCkudHJhbnNwb3J0O1xuLyoqXG4gKiBUaGUgVHJhbnNwb3J0IG9iamVjdCBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tUcmFuc3BvcnRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zcG9ydCgpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLnRyYW5zcG9ydDtcbn1cbi8qKlxuICogVGhlIERlc3RpbmF0aW9uIChvdXRwdXQpIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW0Rlc3RpbmF0aW9uXV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEZXN0aW5hdGlvbiA9IGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNlIFtbRGVzdGluYXRpb25dXVxuICovXG5leHBvcnQgY29uc3QgTWFzdGVyID0gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xuLyoqXG4gKiBUaGUgRGVzdGluYXRpb24gKG91dHB1dCkgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbRGVzdGluYXRpb25dXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlc3RpbmF0aW9uKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG59XG4vKipcbiAqIFRoZSBbW0xpc3RlbmVyXV0gYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IExpc3RlbmVyID0gZ2V0Q29udGV4dCgpLmxpc3RlbmVyO1xuLyoqXG4gKiBUaGUgW1tMaXN0ZW5lcl1dIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaXN0ZW5lcigpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmxpc3RlbmVyO1xufVxuLyoqXG4gKiBEcmF3IGlzIHVzZWQgdG8gc3luY2hyb25pemUgdGhlIGRyYXcgZnJhbWUgd2l0aCB0aGUgVHJhbnNwb3J0J3MgY2FsbGJhY2tzLlxuICogU2VlIFtbRHJhd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgRHJhdyA9IGdldENvbnRleHQoKS5kcmF3O1xuLyoqXG4gKiBHZXQgdGhlIHNpbmdsZXRvbiBhdHRhY2hlZCB0byB0aGUgZ2xvYmFsIGNvbnRleHQuXG4gKiBEcmF3IGlzIHVzZWQgdG8gc3luY2hyb25pemUgdGhlIGRyYXcgZnJhbWUgd2l0aCB0aGUgVHJhbnNwb3J0J3MgY2FsbGJhY2tzLlxuICogU2VlIFtbRHJhd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RHJhdygpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmRyYXc7XG59XG4vKipcbiAqIEEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgY29udGV4dFxuICogU2VlIFtbQ29udGV4dF1dXG4gKi9cbmV4cG9ydCBjb25zdCBjb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuLyoqXG4gKiBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gYWxsIG9mIHRoZSBsb2FkaW5nIHByb21pc2VzIGFyZSByZXNvbHZlZC5cbiAqIEFsaWFzIGZvciBzdGF0aWMgW1tUb25lQXVkaW9CdWZmZXIubG9hZGVkXV0gbWV0aG9kLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWRlZCgpIHtcbiAgICByZXR1cm4gVG9uZUF1ZGlvQnVmZmVyLmxvYWRlZCgpO1xufVxuLy8gdGhpcyBmaWxscyBpbiBuYW1lIGNoYW5nZXMgZnJvbSAxMy54IHRvIDE0LnhcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL3NvdXJjZS9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlciA9IFRvbmVBdWRpb0J1ZmZlcjtcbmV4cG9ydCBjb25zdCBCdWZmZXJzID0gVG9uZUF1ZGlvQnVmZmVycztcbmV4cG9ydCBjb25zdCBCdWZmZXJTb3VyY2UgPSBUb25lQnVmZmVyU291cmNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuaW1wb3J0IFN0YXJ0QXVkaW9Db250ZXh0IGZyb20gXCIuL3N0YXJ0QXVkaW9Db250ZXh0XCI7XG5cbmNvbnN0IGlzSXBob25lID1cbiAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lL2kpIHx8IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQb2QvaSk7XG5jb25zdCBpc0lwYWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGFkL2kpO1xuY29uc3QgaXNBbmRyb2lkID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKTtcbmNvbnN0IGlzTW9iaWxlID0gaXNJcGhvbmUgfHwgaXNJcGFkIHx8IGlzQW5kcm9pZDtcbmNvbnN0IGlzRGVza3RvcCA9ICFpc01vYmlsZTtcblxuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKGlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwiKTtcblxuZXhwb3J0IGNvbnN0IGJyb3dzZXIgPSB7IGlzSXBob25lLCBpc0lwYWQsIGlzTW9iaWxlLCBpc0Rlc2t0b3AgfTtcbmV4cG9ydCBjb25zdCBjaG9pY2UgPSAoYSkgPT4gYVtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhLmxlbmd0aCldO1xuZXhwb3J0IGNvbnN0IG1vZCA9IChuLCBtKSA9PiBuIC0gbSAqIE1hdGguZmxvb3IobiAvIG0pO1xuZXhwb3J0IGNvbnN0IHJhbmRvbSA9ICgpID0+IE1hdGgucmFuZG9tKCk7XG5leHBvcnQgY29uc3QgcmFuZCA9IChuKSA9PiBNYXRoLnJhbmRvbSgpICogbjtcbmV4cG9ydCBjb25zdCByYW5kaW50ID0gKG4pID0+IHJhbmQobikgfCAwO1xuZXhwb3J0IGNvbnN0IHJhbmRyYW5nZSA9IChhLCBiKSA9PiBhICsgcmFuZChiIC0gYSk7XG5leHBvcnQgY29uc3QgcmFuZHNpZ24gPSAoKSA9PiAocmFuZG9tKCkgPj0gMC41ID8gLTEgOiAxKTtcbmV4cG9ydCBjb25zdCByYW5kbnVsbHNpZ24gPSAoKSA9PiB7XG4gIHZhciByID0gcmFuZG9tKCk7XG4gIHJldHVybiByIDwgMC4zMzMgPyAtMSA6IHIgPCAwLjY2NiA/IDAgOiAxO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcXVlc3RBdWRpb0NvbnRleHQoZm4pIHtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYnV0dG9uLmlubmVySFRNTCA9IFwiVGFwIHRvIHN0YXJ0IC0gcGxlYXNlIHVubXV0ZSB5b3VyIGRldmljZVwiO1xuICBPYmplY3QuYXNzaWduKGNvbnRhaW5lci5zdHlsZSwge1xuICAgIGRpc3BsYXk6IFwiYmxvY2tcIixcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIHdpZHRoOiBcIjEwMCVcIixcbiAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgIHpJbmRleDogXCIxMDAwMFwiLFxuICAgIHRvcDogXCIwcHhcIixcbiAgICBsZWZ0OiBcIjBweFwiLFxuICAgIGJhY2tncm91bmRDb2xvcjogXCJyZ2JhKDAsIDAsIDAsIDAuOClcIixcbiAgfSk7XG4gIE9iamVjdC5hc3NpZ24oYnV0dG9uLnN0eWxlLCB7XG4gICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgbGVmdDogXCI1MCVcIixcbiAgICB0b3A6IFwiNTAlXCIsXG4gICAgcGFkZGluZzogXCIyMHB4XCIsXG4gICAgYmFja2dyb3VuZENvbG9yOiBcIiM3RjMzRURcIixcbiAgICBjb2xvcjogXCJ3aGl0ZVwiLFxuICAgIGZvbnRGYW1pbHk6IFwiJ01lbmxvJywgbW9ub3NwYWNlXCIsXG4gICAgYm9yZGVyUmFkaXVzOiBcIjNweFwiLFxuICAgIHRyYW5zZm9ybTogXCJ0cmFuc2xhdGUzRCgtNTAlLC01MCUsMClcIixcbiAgICB0ZXh0QWxpZ246IFwiY2VudGVyXCIsXG4gICAgbGluZUhlaWdodDogXCIxLjVcIixcbiAgICB3aWR0aDogXCIxNTBweFwiLFxuICAgIGN1cnNvcjogXCJwb2ludGVyXCIsXG4gIH0pO1xuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoYnV0dG9uKTtcbiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0KFRvbmUuY29udGV4dCk7XG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGJ1dHRvbik7XG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uU3RhcnRlZCgoXykgPT4ge1xuICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICBmbigpO1xuICB9KTtcbn1cbiIsIi8qKlxuICogUmVsYWJpIHdhdmVmb3JtIGRpc3BsYXlcbiAqIEBtb2R1bGUgc3JjL3JlbGFiaS9jYW52YXMuanM7XG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVsYWJpQ2FudmFzIHtcbiAgLyoqXG4gICAqIEluaXRpYWxpemUgcmVsYWJpIHdhdmUgcmVuZGVyZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKHsgcmVsYWJpLCBwYXJlbnQgfSkge1xuICAgIHRoaXMucmVsYWJpID0gcmVsYWJpO1xuICAgIHRoaXMuaGVpZ2h0ID0gNDAwO1xuICAgIHRoaXMubGFzdEZyYW1lID0gMDtcbiAgICB0aGlzLmxhc3RBcHBlbmRUaW1lID0gMDtcbiAgICB0aGlzLmxhc3RBcHBlbmRGcmFtZSA9IDA7XG5cbiAgICAvLyBTcGVlZCBvZiB0aGUgd2F2ZSBpbiBwaXhlbHMgcGVyIHNlY29uZFxuICAgIHRoaXMuc3BlZWQgPSAxIC8gNTtcblxuICAgIC8vIFBvc2l0aW9uIG9mIGN1cnJlbnQgdGltZSBvbiB0aGUgc2NyZWVuLCBmcm9tIHRoZSBsZWZ0XG4gICAgdGhpcy50WmVyb09mZnNldCA9IDIwO1xuXG4gICAgLy8gQXR0YWNoIHRvIHRoZSBET01cbiAgICB0aGlzLmFwcGVuZENhbnZhcyhwYXJlbnQpO1xuICAgIC8vIEluaXRpYWxpemUgYXJyYXlcbiAgICB0aGlzLnZhbHVlcyA9IG5ldyBBcnJheSh3aW5kb3cuaW5uZXJXaWR0aCkuZmlsbCgwKTtcbiAgICB0aGlzLm5vdGVzID0gW107XG4gICAgdGhpcy5hcHBlbmQoW10pO1xuXG4gICAgLy8gQ2xlYXIgdGhlIGNhbnZhc1xuICAgIHRoaXMucmVzaXplKCk7XG5cbiAgICAvLyBTdGFydCBkcmF3aW5nXG4gICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoMCk7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kIHRoZSBjYW52YXNcbiAgICovXG4gIGFwcGVuZENhbnZhcyhwYXJlbnQpIHtcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudCB8fCBkb2N1bWVudC5ib2R5O1xuICAgIHRoaXMuY2FudmFzID0gdGhpcy5jYW52YXMgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICB0aGlzLmN0eCA9IHRoaXMuY3R4IHx8IHRoaXMuY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmNhbnZhcyk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgbmV4dCBmcmFtZVxuICAgKi9cbiAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZyYW1lKSB7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKChmcmFtZSkgPT4ge1xuICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnJhbWUpO1xuICAgIH0pO1xuICAgIHRoaXMucGFpbnQoZnJhbWUpO1xuICAgIHRoaXMubGFzdEZyYW1lID0gZnJhbWU7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHdpbmRvdyByZXNpemVcbiAgICovXG4gIHJlc2l6ZSgpIHtcbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIHRoZSBjYW52YXNcbiAgICovXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmQgdmFsdWVzXG4gICAqL1xuICBhcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcykge1xuICAgIHRoaXMubGFzdEFwcGVuZFRpbWUgPSB0aW1lO1xuICAgIHRoaXMubGFzdEFwcGVuZEZyYW1lID0gdGhpcy5sYXN0RnJhbWU7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlc1xuICAgICAgLmZpbHRlcigodmFsdWUpID0+IHZhbHVlICYmIHZhbHVlWzBdIDwgdGltZSlcbiAgICAgIC5jb25jYXQodmFsdWVzKVxuICAgICAgLnNsaWNlKC10aGlzLmNhbnZhcy53aWR0aClcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG5cbiAgICBpZiAobm90ZXM/Lmxlbmd0aCkge1xuICAgICAgdGhpcy5ub3RlcyA9IHRoaXMubm90ZXNcbiAgICAgICAgLmNvbmNhdChub3RlcylcbiAgICAgICAgLnNsaWNlKC01MClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFpbnQgdGhlIGNhbnZhc1xuICAgKi9cbiAgcGFpbnQoZnJhbWUpIHtcbiAgICB0aGlzLmNsZWFyKCk7XG4gICAgdGhpcy5kcmF3UmVsYWJpV2F2ZShmcmFtZSk7XG4gICAgdGhpcy5kcmF3Qm91bmRzKCk7XG4gICAgdGhpcy5kcmF3Tm90ZXMoZnJhbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIGJvdW5kc1xuICAgKi9cbiAgZHJhd0JvdW5kcygpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgLy8gRHJhdyBkYXNoZWQgbGluZXMgZm9yIGFsbCBib3VuZHNcbiAgICBmb3IgKGNvbnN0IGJvdW5kIG9mIHRoaXMucmVsYWJpLmJvdW5kcykge1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQoYm91bmQubGV2ZWwsIGhlaWdodCk7XG5cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5zZXRMaW5lRGFzaChbNCwgNF0pO1xuICAgICAgY3R4LmxpbmVXaWR0aCA9IDE7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBib3VuZC5jb2xvciB8fCBcIiM4ODhcIjtcbiAgICAgIGN0eC5tb3ZlVG8oMCwgeSk7XG4gICAgICBjdHgubGluZVRvKHdpZHRoLCB5KTtcbiAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG5cbiAgICAvLyBEcmF3IHRoZSB6ZXJvIHBvc2l0aW9uXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5zZXRMaW5lRGFzaChbMSwgMV0pO1xuICAgIGN0eC5saW5lV2lkdGggPSAyO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiIzY2NlwiO1xuICAgIGN0eC5tb3ZlVG8od2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0LCAwKTtcbiAgICBjdHgubGluZVRvKHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCwgaGVpZ2h0KTtcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgcmVsYWJpIHdhdmVcbiAgICovXG4gIGRyYXdSZWxhYmlXYXZlKGZyYW1lKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIGNvbnN0IHBvaW50Q291bnQgPSB0aGlzLnZhbHVlcy5sZW5ndGg7XG4gICAgbGV0IGluZGV4ID0gMDtcblxuICAgIC8vIFN0YXJ0IHRoZSBwYXRoXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiI2RmZlwiO1xuICAgIGN0eC5saW5lV2lkdGggPSAxLjE7XG4gICAgY3R4LnNldExpbmVEYXNoKFtdKTtcblxuICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBpbiBzZWNvbmRzIGZyb20gdGhlIGxhc3QgZnJhbWUgd2UgY29tcHV0ZWRcbiAgICBjb25zdCBmcmFtZU9mZnNldCA9IChmcmFtZSAtIHRoaXMubGFzdEFwcGVuZEZyYW1lKSAvIDEwMDA7XG5cbiAgICAvLyBNYWtlIGEgcGF0aCBjb25uZWN0aW5nIGFsbCB2YWx1ZXNcbiAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHRoaXMudmFsdWVzKSB7XG4gICAgICBpZiAoIXBvaW50KSB7XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gcG9pbnQ7XG5cbiAgICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBvZiB0aGlzIHRpbWUgZnJvbSBjdXJyZW50IHRpbWVcbiAgICAgIC8vIElmIHRoaXMgaXMgaW4gdGhlIGZ1dHVyZSwgaXQgd2lsbCBiZSBwb3NpdGl2ZS5cbiAgICAgIC8vIFN1YnRyYWN0aW5nIHRoZSBmcmFtZSBvZmZzZXQgcHVsbHMgaXQgbmVnYXRpdmUuXG4gICAgICBjb25zdCB0aW1lT2Zmc2V0ID0gdGhpcy5sYXN0QXBwZW5kVGltZSArIGZyYW1lT2Zmc2V0IC0gdGltZTtcblxuICAgICAgY29uc3QgeCA9IHdpZHRoIC0gdGltZU9mZnNldCAqIHRoaXMuc3BlZWQgKiB3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQ7XG4gICAgICBjb25zdCB5ID0gZ2V0V2F2ZUhlaWdodCh2YWx1ZSwgaGVpZ2h0KTtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgY3R4Lm1vdmVUbyh4LCB5KTtcbiAgICAgIH1cbiAgICAgIGN0eC5saW5lVG8oeCwgeSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cblxuICAgIC8vIFBhaW50IHRoZSBsaW5lXG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIG5vdGVzXG4gICAqL1xuICBkcmF3Tm90ZXMoZnJhbWUpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IGluIHNlY29uZHMgZnJvbSB0aGUgbGFzdCBmcmFtZSB3ZSBjb21wdXRlZFxuICAgIGNvbnN0IGZyYW1lT2Zmc2V0ID0gKGZyYW1lIC0gdGhpcy5sYXN0QXBwZW5kRnJhbWUpIC8gMTAwMDtcblxuICAgIC8vIE1ha2UgYSBwYXRoIGNvbm5lY3RpbmcgYWxsIHZhbHVlc1xuICAgIGZvciAoY29uc3Qgbm90ZSBvZiB0aGlzLm5vdGVzKSB7XG4gICAgICBjb25zdCBbdGltZSwgdmFsdWUsIGRpcmVjdGlvbl0gPSBub3RlO1xuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRoaXMubGFzdEFwcGVuZFRpbWUgKyBmcmFtZU9mZnNldCAtIHRpbWU7XG4gICAgICBjb25zdCB4ID0gd2lkdGggLSB0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoIC0gdGhpcy50WmVyb09mZnNldDtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KHZhbHVlLCBoZWlnaHQpO1xuXG4gICAgICAvLyBEb24ndCBkcmF3IG5vdGVzIHRoYXQgaGF2ZW4ndCBwbGF5ZWQgeWV0XG4gICAgICBpZiAoeCA+IHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gRHJhdyBub3RlcyBhcyBhIGRvdCB0aGF0IGZhZGVzIG91dFxuICAgICAgY29uc3Qgb3BhY2l0eSA9IDEgLSAodGltZU9mZnNldCAqIHRoaXMuc3BlZWQgKiB3aWR0aCkgLyAxMDAwO1xuICAgICAgaWYgKG9wYWNpdHkgPCAwLjAwMSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5hcmMoeCAtIDIuNSwgeSwgNSwgMCwgMiAqIE1hdGguUEkpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IGRpcmVjdGlvblxuICAgICAgICA/IGByZ2JhKDI1NSwxMjgsMTkyLCR7b3BhY2l0eX0pYFxuICAgICAgICA6IGByZ2JhKDE5MiwyNTUsMTI4LCR7b3BhY2l0eX0pYDtcbiAgICAgIGN0eC5maWxsKCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBoZWlnaHQgb2YgdGhlIHdhdmUgYXQgYSBnaXZlbiB2YWx1ZVxuICovXG5jb25zdCBnZXRXYXZlSGVpZ2h0ID0gKHZhbHVlLCBoZWlnaHQpID0+ICgodmFsdWUgKyAxKSAvIDIpICogaGVpZ2h0O1xuIiwiLyoqXG4gKiBSZWxhYmkgZXZlbnQgZ2VuZXJhdG9yXG4gKi9cblxuaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuaW1wb3J0IFJlbGFiaUNhbnZhcyBmcm9tIFwiLi9jYW52YXNcIjtcblxuY29uc3QgVFdPX1BJID0gMiAqIE1hdGguUEk7XG5cbi8qKlxuICogV2F2ZSBmdW5jdGlvbnNcbiAqL1xuY29uc3QgV0FWRV9TSEFQRVMgPSB7XG4gIHNpbmU6IE1hdGguY29zLFxuICB0cmlhbmdsZTogKHRpbWUpID0+XG4gICAgKDQgLyBUV09fUEkpICpcbiAgICAgIE1hdGguYWJzKFxuICAgICAgICAoKCgodGltZSAtIFRXT19QSSAvIDQpICUgVFdPX1BJKSArIFRXT19QSSkgJSBUV09fUEkpIC0gVFdPX1BJIC8gMlxuICAgICAgKSAtXG4gICAgMSxcbiAgc3F1YXJlOiAodGltZSkgPT4gKHRpbWUgJSBUV09fUEkgPCBNYXRoLlBJID8gMSA6IC0xKSxcbiAgc2F3OiAodGltZSkgPT4gKCh0aW1lICUgVFdPX1BJKSAtIE1hdGguUEkpIC8gTWF0aC5QSSxcbn07XG5cbi8qKlxuICogUmVsYWJpIGdlbmVyYXRvclxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWxhYmkge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSBnZW5lcmF0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKHsgd2F2ZXMsIGJvdW5kcywgcGFyZW50IH0pIHtcbiAgICB0aGlzLnVwZGF0ZVRpbWUgPSAxO1xuICAgIHRoaXMuc3RlcHMgPSA1MDtcbiAgICB0aGlzLndhdmVzID0gd2F2ZXMgfHwgW1xuICAgICAgeyBzaGFwZTogXCJ0cmlhbmdsZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSgwLjUsIDEuNSkgfSxcbiAgICAgIHsgc2hhcGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC43NSwgMi4yNSkgfSxcbiAgICAgIHsgc2hhcGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMSwgMykgfSxcbiAgICAgIHsgc2hhcGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMiwgNCkgfSxcbiAgICBdO1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMucHJldmlvdXNWYWx1ZSA9IG51bGw7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgUmVsYWJpQ2FudmFzKHsgcmVsYWJpOiB0aGlzLCBwYXJlbnQgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgdGhlIGdlbmVyYXRvclxuICAgKi9cbiAgc3RhcnQoKSB7XG4gICAgY29uc29sZS5sb2coXCJTdGFydCBSZWxhYmlcIik7XG4gICAgdGhpcy5zdG9wKCk7XG4gICAgdGhpcy5jbG9jayA9IG5ldyBUb25lLkNsb2NrKCh0aW1lKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLmdlbmVyYXRlKHRpbWUpO1xuICAgICAgY29uc3Qgbm90ZXMgPSB0aGlzLnBsYXkodmFsdWVzKTtcbiAgICAgIHRoaXMuY2FudmFzLmFwcGVuZCh0aW1lLCB2YWx1ZXMsIG5vdGVzKTtcbiAgICB9LCB0aGlzLnVwZGF0ZVRpbWUpO1xuICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIHRoZSBnZW5lcmF0b3IgYW5kIHJlc2V0IGl0XG4gICAqL1xuICBzdG9wKCkge1xuICAgIGlmICh0aGlzLmNsb2NrKSB7XG4gICAgICB0aGlzLmNsb2NrLnN0b3AoKTtcbiAgICAgIHRoaXMuY2xvY2suZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBnZW5lcmF0ZSh0aW1lKSB7XG4gICAgY29uc3Qgd2F2ZUNvdW50ID0gdGhpcy53YXZlcy5sZW5ndGg7XG4gICAgbGV0IGluZGV4O1xuICAgIGxldCBzdGVwO1xuICAgIGxldCB2YWx1ZTtcbiAgICBsZXQgdmFsdWVzID0gW107XG5cbiAgICAvLyBPdmVyc2hvb3QgdGhlIGxpbmUgc2xpZ2h0bHkgZWFjaCB0aW1lXG4gICAgbGV0IHN0ZXBDb3VudCA9IHRoaXMuc3RlcHMgKyAyMDtcblxuICAgIC8vIEdlbmVyYXRlIHNldmVyYWwgZXZlbnRzIHBlciBzZWNvbmRcbiAgICBmb3IgKHN0ZXAgPSAwOyBzdGVwIDwgc3RlcENvdW50OyBzdGVwICs9IDEpIHtcbiAgICAgIC8vIFRpbWUgb2Zmc2V0IGZvciB0aGlzIGV2ZW50XG4gICAgICBjb25zdCB0aW1lT2Zmc2V0ID0gdGltZSArIChzdGVwICogdGhpcy51cGRhdGVUaW1lKSAvIHRoaXMuc3RlcHM7XG5cbiAgICAgIC8vIEluaXRpYWxpemUgdmFsdWVcbiAgICAgIHZhbHVlID0gMDtcblxuICAgICAgLy8gQ29tcHV0ZSB0aGUgd2F2ZSBmdW5jdGlvbnMgZm9yIHRoaXMgZXZlbnRcbiAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IHdhdmVDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCB3YXZlID0gdGhpcy53YXZlc1tpbmRleF07XG4gICAgICAgIHZhbHVlICs9IFdBVkVfU0hBUEVTW3dhdmUuc2hhcGVdKHRpbWVPZmZzZXQgKiB3YXZlLmZyZXF1ZW5jeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNjYWxlIHRvIFstMSwgMV1cbiAgICAgIHZhbHVlIC89IHdhdmVDb3VudDtcblxuICAgICAgdmFsdWVzLnB1c2goW3RpbWVPZmZzZXQsIHZhbHVlXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBwbGF5KHZhbHVlcykge1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgbm90ZUNvdW50ID0gMDtcbiAgICBjb25zdCBub3RlcyA9IFtdO1xuXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gR2V0IHRoZSBuZXh0IHZhbHVlXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gdmFsdWVzW3N0ZXBdO1xuXG4gICAgICAvLyBDb21wdXRlIHdoZXRoZXIgd2UgY3Jvc3NlZCBhIGJvdW5kYXJ5LCBhbmQgd2hpY2ggZGlyZWN0aW9uXG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBib3VuZHNDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBib3VuZCA9IHRoaXMuYm91bmRzW2luZGV4XTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlIDwgYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIodGltZSwgYm91bmQuc291bmRzWzBdKTtcbiAgICAgICAgICBub3Rlcy5wdXNoKFt0aW1lLCBib3VuZC5sZXZlbCwgdHJ1ZV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHZhbHVlID4gYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA+IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIHVwXG4gICAgICAgICAgdGhpcy50cmlnZ2VyKHRpbWUsIGJvdW5kLnNvdW5kc1sxXSk7XG4gICAgICAgICAgbm90ZXMucHVzaChbdGltZSwgYm91bmQubGV2ZWwsIGZhbHNlXSk7XG4gICAgICAgICAgbm90ZUNvdW50ICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgcHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSBsYXRlc3QgdmFsdWVcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgLy8gUmV0dXJuIHRoZSBub3Rlc1xuICAgIHJldHVybiBub3RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGV2ZW50XG4gICAqL1xuICB0cmlnZ2VyKHRpbWUsIHNvdW5kKSB7XG4gICAgLy8gY29uc29sZS5sb2coXCJ0cmlnZ2VyIGluZGV4XCIsIGluZGV4LCB0aW1lKTtcbiAgICBzb3VuZC5pbnN0cnVtZW50LnBsYXkodGltZSwgc291bmQpO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5cbmNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5jb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigwLjMpO1xuY29tcHJlc3Nvci5jb25uZWN0KGdhaW4pO1xuZ2Fpbi50b0Rlc3RpbmF0aW9uKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNvbXByZXNzb3I7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgeyBjaG9pY2UsIHJhbmRyYW5nZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IFBMQVlFUl9DT1VOVCA9IDQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNhbXBsZXIge1xuICBjb25zdHJ1Y3Rvcih7IHNhbXBsZXMsIHRvbmFsIH0pIHtcbiAgICB0aGlzLnRvbmFsID0gdG9uYWw7XG4gICAgdGhpcy5zYW1wbGVzID0gc2FtcGxlcy5tYXAoKHsgLi4uc2FtcGxlIH0pID0+IHtcbiAgICAgIHNhbXBsZS5wbGF5ZXJzID0gW107XG4gICAgICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUExBWUVSX0NPVU5UOyBpKyspIHtcbiAgICAgICAgbGV0IGZuID0gc2FtcGxlLmZuO1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgICAgIGZuID0gXCIvL2FzZGYudXMva2FsaW1iYS9cIiArIGZuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgICAgIHVybDogZm4sXG4gICAgICAgICAgcmV0cmlnZ2VyOiB0cnVlLFxuICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBsYXllci5jb25uZWN0KG91dHB1dCk7XG4gICAgICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW1wbGU7XG4gICAgfSk7XG4gIH1cblxuICBwbGF5KHRpbWUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VuZCA9IG9wdGlvbnMuaW5kZXhcbiAgICAgID8gdGhpcy5zYW1wbGVzW29wdGlvbnMuaW5kZXhdXG4gICAgICA6IGNob2ljZSh0aGlzLnNhbXBsZXMpO1xuXG4gICAgc291bmQuaW5kZXggPSAoc291bmQuaW5kZXggKyAxKSAlIFBMQVlFUl9DT1VOVDtcblxuICAgIGNvbnN0IHBsYXllciA9IHNvdW5kLnBsYXllcnNbc291bmQuaW5kZXhdO1xuXG4gICAgaWYgKHRoaXMudG9uYWwpIHtcbiAgICAgIHBsYXllci5wbGF5YmFja1JhdGUgPVxuICAgICAgICAob3B0aW9ucy5mcmVxdWVuY3kgKiBjaG9pY2UoWzAuNSwgMV0pICsgcmFuZHJhbmdlKDAsIDEwKSkgLyBzb3VuZC5yb290O1xuICAgIH1cblxuICAgIHBsYXllci5zdGFydCh0aW1lIHx8IDApO1xuICB9XG59XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9zYW1wbGVyXCI7XG5cbmV4cG9ydCBjb25zdCBLYWxpbWJhID0gbmV3IFNhbXBsZXIoe1xuICB0b25hbDogdHJ1ZSxcbiAgc2FtcGxlczogW1xuICAgIHsgcm9vdDogMjI2LCBmbjogXCJzYW1wbGVzLzM4MDczN19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDEtYS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAzNDAsIGZuOiBcInNhbXBsZXMvMzgwNzM1X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMy1lLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogNDUyLCBmbjogXCJzYW1wbGVzLzM4MDczM19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDYtYS0wMi1yYXcubXAzXCIgfSxcbiAgXSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRHJ1bXMgPSBuZXcgU2FtcGxlcih7XG4gIHRvbmFsOiBmYWxzZSxcbiAgc2FtcGxlczogW1xuICAgIHsgZm46IFwic2FtcGxlcy83MDdfYmQubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NsYXAubXAzXCIgfSxcbiAgICAvLyB7IGZuOiBcInNhbXBsZXMvNzA3X2Nvdy5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfaGF0Lm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19yaW0ubXAzXCIgfSxcbiAgXSxcbn0pO1xuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3R5cGVvZihvYmopIHtcbiAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gIHJldHVybiBfdHlwZW9mID0gXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgXCJzeW1ib2xcIiA9PSB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID8gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqO1xuICB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBvYmogJiYgXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG4gIH0sIF90eXBlb2Yob2JqKTtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiLi90eXBlb2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF90b1ByaW1pdGl2ZShpbnB1dCwgaGludCkge1xuICBpZiAoX3R5cGVvZihpbnB1dCkgIT09IFwib2JqZWN0XCIgfHwgaW5wdXQgPT09IG51bGwpIHJldHVybiBpbnB1dDtcbiAgdmFyIHByaW0gPSBpbnB1dFtTeW1ib2wudG9QcmltaXRpdmVdO1xuICBpZiAocHJpbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIHJlcyA9IHByaW0uY2FsbChpbnB1dCwgaGludCB8fCBcImRlZmF1bHRcIik7XG4gICAgaWYgKF90eXBlb2YocmVzKSAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHJlcztcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQEB0b1ByaW1pdGl2ZSBtdXN0IHJldHVybiBhIHByaW1pdGl2ZSB2YWx1ZS5cIik7XG4gIH1cbiAgcmV0dXJuIChoaW50ID09PSBcInN0cmluZ1wiID8gU3RyaW5nIDogTnVtYmVyKShpbnB1dCk7XG59IiwiaW1wb3J0IF90eXBlb2YgZnJvbSBcIi4vdHlwZW9mLmpzXCI7XG5pbXBvcnQgdG9QcmltaXRpdmUgZnJvbSBcIi4vdG9QcmltaXRpdmUuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF90b1Byb3BlcnR5S2V5KGFyZykge1xuICB2YXIga2V5ID0gdG9QcmltaXRpdmUoYXJnLCBcInN0cmluZ1wiKTtcbiAgcmV0dXJuIF90eXBlb2Yoa2V5KSA9PT0gXCJzeW1ib2xcIiA/IGtleSA6IFN0cmluZyhrZXkpO1xufSIsImltcG9ydCB0b1Byb3BlcnR5S2V5IGZyb20gXCIuL3RvUHJvcGVydHlLZXkuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgdmFsdWUpIHtcbiAga2V5ID0gdG9Qcm9wZXJ0eUtleShrZXkpO1xuICBpZiAoa2V5IGluIG9iaikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gb2JqO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hcnJheUxpa2VUb0FycmF5KGFyciwgbGVuKSB7XG4gIGlmIChsZW4gPT0gbnVsbCB8fCBsZW4gPiBhcnIubGVuZ3RoKSBsZW4gPSBhcnIubGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShsZW4pOyBpIDwgbGVuOyBpKyspIGFycjJbaV0gPSBhcnJbaV07XG4gIHJldHVybiBhcnIyO1xufSIsImltcG9ydCBhcnJheUxpa2VUb0FycmF5IGZyb20gXCIuL2FycmF5TGlrZVRvQXJyYXkuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hcnJheVdpdGhvdXRIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycmF5TGlrZVRvQXJyYXkoYXJyKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5KGl0ZXIpIHtcbiAgaWYgKHR5cGVvZiBTeW1ib2wgIT09IFwidW5kZWZpbmVkXCIgJiYgaXRlcltTeW1ib2wuaXRlcmF0b3JdICE9IG51bGwgfHwgaXRlcltcIkBAaXRlcmF0b3JcIl0gIT0gbnVsbCkgcmV0dXJuIEFycmF5LmZyb20oaXRlcik7XG59IiwiaW1wb3J0IGFycmF5TGlrZVRvQXJyYXkgZnJvbSBcIi4vYXJyYXlMaWtlVG9BcnJheS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KG8sIG1pbkxlbikge1xuICBpZiAoIW8pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBvID09PSBcInN0cmluZ1wiKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xuICB2YXIgbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKS5zbGljZSg4LCAtMSk7XG4gIGlmIChuID09PSBcIk9iamVjdFwiICYmIG8uY29uc3RydWN0b3IpIG4gPSBvLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGlmIChuID09PSBcIk1hcFwiIHx8IG4gPT09IFwiU2V0XCIpIHJldHVybiBBcnJheS5mcm9tKG8pO1xuICBpZiAobiA9PT0gXCJBcmd1bWVudHNcIiB8fCAvXig/OlVpfEkpbnQoPzo4fDE2fDMyKSg/OkNsYW1wZWQpP0FycmF5JC8udGVzdChuKSkgcmV0dXJuIGFycmF5TGlrZVRvQXJyYXkobywgbWluTGVuKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfbm9uSXRlcmFibGVTcHJlYWQoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gc3ByZWFkIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufSIsImltcG9ydCBhcnJheVdpdGhvdXRIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhvdXRIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi9pdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSBmcm9tIFwiLi91bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IG5vbkl0ZXJhYmxlU3ByZWFkIGZyb20gXCIuL25vbkl0ZXJhYmxlU3ByZWFkLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gIHJldHVybiBhcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFycikgfHwgbm9uSXRlcmFibGVTcHJlYWQoKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXJyYXlXaXRoSG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHJldHVybiBhcnI7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2kgPSBudWxsID09IGFyciA/IG51bGwgOiBcInVuZGVmaW5lZFwiICE9IHR5cGVvZiBTeW1ib2wgJiYgYXJyW1N5bWJvbC5pdGVyYXRvcl0gfHwgYXJyW1wiQEBpdGVyYXRvclwiXTtcbiAgaWYgKG51bGwgIT0gX2kpIHtcbiAgICB2YXIgX3MsXG4gICAgICBfZSxcbiAgICAgIF94LFxuICAgICAgX3IsXG4gICAgICBfYXJyID0gW10sXG4gICAgICBfbiA9ICEwLFxuICAgICAgX2QgPSAhMTtcbiAgICB0cnkge1xuICAgICAgaWYgKF94ID0gKF9pID0gX2kuY2FsbChhcnIpKS5uZXh0LCAwID09PSBpKSB7XG4gICAgICAgIGlmIChPYmplY3QoX2kpICE9PSBfaSkgcmV0dXJuO1xuICAgICAgICBfbiA9ICExO1xuICAgICAgfSBlbHNlIGZvciAoOyAhKF9uID0gKF9zID0gX3guY2FsbChfaSkpLmRvbmUpICYmIChfYXJyLnB1c2goX3MudmFsdWUpLCBfYXJyLmxlbmd0aCAhPT0gaSk7IF9uID0gITApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgX2QgPSAhMCwgX2UgPSBlcnI7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghX24gJiYgbnVsbCAhPSBfaVtcInJldHVyblwiXSAmJiAoX3IgPSBfaVtcInJldHVyblwiXSgpLCBPYmplY3QoX3IpICE9PSBfcikpIHJldHVybjtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZCkgdGhyb3cgX2U7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBfYXJyO1xuICB9XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX25vbkl0ZXJhYmxlUmVzdCgpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBkZXN0cnVjdHVyZSBub24taXRlcmFibGUgaW5zdGFuY2UuXFxuSW4gb3JkZXIgdG8gYmUgaXRlcmFibGUsIG5vbi1hcnJheSBvYmplY3RzIG11c3QgaGF2ZSBhIFtTeW1ib2wuaXRlcmF0b3JdKCkgbWV0aG9kLlwiKTtcbn0iLCJpbXBvcnQgYXJyYXlXaXRoSG9sZXMgZnJvbSBcIi4vYXJyYXlXaXRoSG9sZXMuanNcIjtcbmltcG9ydCBpdGVyYWJsZVRvQXJyYXlMaW1pdCBmcm9tIFwiLi9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qc1wiO1xuaW1wb3J0IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IGZyb20gXCIuL3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5LmpzXCI7XG5pbXBvcnQgbm9uSXRlcmFibGVSZXN0IGZyb20gXCIuL25vbkl0ZXJhYmxlUmVzdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3NsaWNlZFRvQXJyYXkoYXJyLCBpKSB7XG4gIHJldHVybiBhcnJheVdpdGhIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkgfHwgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyLCBpKSB8fCBub25JdGVyYWJsZVJlc3QoKTtcbn0iLCIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG52YXIgd2FybmVkID0ge307XG52YXIgcHJlV2FybmluZ0ZucyA9IFtdO1xuXG4vKipcbiAqIFByZSB3YXJuaW5nIGVuYWJsZSB5b3UgdG8gcGFyc2UgY29udGVudCBiZWZvcmUgY29uc29sZS5lcnJvci5cbiAqIE1vZGlmeSB0byBudWxsIHdpbGwgcHJldmVudCB3YXJuaW5nLlxuICovXG5leHBvcnQgdmFyIHByZU1lc3NhZ2UgPSBmdW5jdGlvbiBwcmVNZXNzYWdlKGZuKSB7XG4gIHByZVdhcm5pbmdGbnMucHVzaChmbik7XG59O1xuZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmcodmFsaWQsIG1lc3NhZ2UpIHtcbiAgLy8gU3VwcG9ydCB1Z2xpZnlcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIXZhbGlkICYmIGNvbnNvbGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBmaW5hbE1lc3NhZ2UgPSBwcmVXYXJuaW5nRm5zLnJlZHVjZShmdW5jdGlvbiAobXNnLCBwcmVNZXNzYWdlRm4pIHtcbiAgICAgIHJldHVybiBwcmVNZXNzYWdlRm4obXNnICE9PSBudWxsICYmIG1zZyAhPT0gdm9pZCAwID8gbXNnIDogJycsICd3YXJuaW5nJyk7XG4gICAgfSwgbWVzc2FnZSk7XG4gICAgaWYgKGZpbmFsTWVzc2FnZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcIldhcm5pbmc6IFwiLmNvbmNhdChmaW5hbE1lc3NhZ2UpKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiBub3RlKHZhbGlkLCBtZXNzYWdlKSB7XG4gIC8vIFN1cHBvcnQgdWdsaWZ5XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nICYmICF2YWxpZCAmJiBjb25zb2xlICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgZmluYWxNZXNzYWdlID0gcHJlV2FybmluZ0Zucy5yZWR1Y2UoZnVuY3Rpb24gKG1zZywgcHJlTWVzc2FnZUZuKSB7XG4gICAgICByZXR1cm4gcHJlTWVzc2FnZUZuKG1zZyAhPT0gbnVsbCAmJiBtc2cgIT09IHZvaWQgMCA/IG1zZyA6ICcnLCAnbm90ZScpO1xuICAgIH0sIG1lc3NhZ2UpO1xuICAgIGlmIChmaW5hbE1lc3NhZ2UpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIk5vdGU6IFwiLmNvbmNhdChmaW5hbE1lc3NhZ2UpKTtcbiAgICB9XG4gIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiByZXNldFdhcm5lZCgpIHtcbiAgd2FybmVkID0ge307XG59XG5leHBvcnQgZnVuY3Rpb24gY2FsbChtZXRob2QsIHZhbGlkLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsaWQgJiYgIXdhcm5lZFttZXNzYWdlXSkge1xuICAgIG1ldGhvZChmYWxzZSwgbWVzc2FnZSk7XG4gICAgd2FybmVkW21lc3NhZ2VdID0gdHJ1ZTtcbiAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIHdhcm5pbmdPbmNlKHZhbGlkLCBtZXNzYWdlKSB7XG4gIGNhbGwod2FybmluZywgdmFsaWQsIG1lc3NhZ2UpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG5vdGVPbmNlKHZhbGlkLCBtZXNzYWdlKSB7XG4gIGNhbGwobm90ZSwgdmFsaWQsIG1lc3NhZ2UpO1xufVxud2FybmluZ09uY2UucHJlTWVzc2FnZSA9IHByZU1lc3NhZ2U7XG53YXJuaW5nT25jZS5yZXNldFdhcm5lZCA9IHJlc2V0V2FybmVkO1xud2FybmluZ09uY2Uubm90ZU9uY2UgPSBub3RlT25jZTtcbmV4cG9ydCBkZWZhdWx0IHdhcm5pbmdPbmNlO1xuLyogZXNsaW50LWVuYWJsZSAqLyIsImltcG9ydCBfdHlwZW9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2ZcIjtcbmltcG9ydCB3YXJuaW5nIGZyb20gXCIuL3dhcm5pbmdcIjtcblxuLyoqXG4gKiBEZWVwbHkgY29tcGFyZXMgdHdvIG9iamVjdCBsaXRlcmFscy5cbiAqIEBwYXJhbSBvYmoxIG9iamVjdCAxXG4gKiBAcGFyYW0gb2JqMiBvYmplY3QgMlxuICogQHBhcmFtIHNoYWxsb3cgc2hhbGxvdyBjb21wYXJlXG4gKiBAcmV0dXJuc1xuICovXG5mdW5jdGlvbiBpc0VxdWFsKG9iajEsIG9iajIpIHtcbiAgdmFyIHNoYWxsb3cgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IGZhbHNlO1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L21hcGJveC1nbC1qcy9wdWxsLzU5NzkvZmlsZXMjZGlmZi1mZGU3MTQ1MDUwYzQ3Y2MzYTMwNjg1NmVmZDVmOWMzMDE2ZTg2ZTg1OWRlOWFmYmQwMmM4NzliZTUwNjdlNThmXG4gIHZhciByZWZTZXQgPSBuZXcgU2V0KCk7XG4gIGZ1bmN0aW9uIGRlZXBFcXVhbChhLCBiKSB7XG4gICAgdmFyIGxldmVsID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgJiYgYXJndW1lbnRzWzJdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMl0gOiAxO1xuICAgIHZhciBjaXJjdWxhciA9IHJlZlNldC5oYXMoYSk7XG4gICAgd2FybmluZyghY2lyY3VsYXIsICdXYXJuaW5nOiBUaGVyZSBtYXkgYmUgY2lyY3VsYXIgcmVmZXJlbmNlcycpO1xuICAgIGlmIChjaXJjdWxhcikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoYSA9PT0gYikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChzaGFsbG93ICYmIGxldmVsID4gMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZWZTZXQuYWRkKGEpO1xuICAgIHZhciBuZXdMZXZlbCA9IGxldmVsICsgMTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGIpIHx8IGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKCFkZWVwRXF1YWwoYVtpXSwgYltpXSwgbmV3TGV2ZWwpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGEgJiYgYiAmJiBfdHlwZW9mKGEpID09PSAnb2JqZWN0JyAmJiBfdHlwZW9mKGIpID09PSAnb2JqZWN0Jykge1xuICAgICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhKTtcbiAgICAgIGlmIChrZXlzLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYikubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBrZXlzLmV2ZXJ5KGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBFcXVhbChhW2tleV0sIGJba2V5XSwgbmV3TGV2ZWwpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIG90aGVyXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBkZWVwRXF1YWwob2JqMSwgb2JqMik7XG59XG5leHBvcnQgZGVmYXVsdCBpc0VxdWFsOyIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZUV2ZW50KGNhbGxiYWNrKSB7XG4gIHZhciBmblJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICBmblJlZi5jdXJyZW50ID0gY2FsbGJhY2s7XG4gIHZhciBtZW1vRm4gPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9mblJlZiRjdXJyZW50O1xuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIChfZm5SZWYkY3VycmVudCA9IGZuUmVmLmN1cnJlbnQpID09PSBudWxsIHx8IF9mblJlZiRjdXJyZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZm5SZWYkY3VycmVudC5jYWxsLmFwcGx5KF9mblJlZiRjdXJyZW50LCBbZm5SZWZdLmNvbmNhdChhcmdzKSk7XG4gIH0sIFtdKTtcbiAgcmV0dXJuIG1lbW9Gbjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjYW5Vc2VEb20oKSB7XG4gIHJldHVybiAhISh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQgJiYgd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpO1xufSIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBjYW5Vc2VEb20gZnJvbSBcIi4uL0RvbS9jYW5Vc2VEb21cIjtcblxuLyoqXG4gKiBXcmFwIGBSZWFjdC51c2VMYXlvdXRFZmZlY3RgIHdoaWNoIHdpbGwgbm90IHRocm93IHdhcm5pbmcgbWVzc2FnZSBpbiB0ZXN0IGVudlxuICovXG52YXIgdXNlTGF5b3V0RWZmZWN0ID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICd0ZXN0JyAmJiBjYW5Vc2VEb20oKSA/IFJlYWN0LnVzZUxheW91dEVmZmVjdCA6IFJlYWN0LnVzZUVmZmVjdDtcbmV4cG9ydCBkZWZhdWx0IHVzZUxheW91dEVmZmVjdDtcbmV4cG9ydCB2YXIgdXNlTGF5b3V0VXBkYXRlRWZmZWN0ID0gZnVuY3Rpb24gdXNlTGF5b3V0VXBkYXRlRWZmZWN0KGNhbGxiYWNrLCBkZXBzKSB7XG4gIHZhciBmaXJzdE1vdW50UmVmID0gUmVhY3QudXNlUmVmKHRydWUpO1xuICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmICghZmlyc3RNb3VudFJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB9XG4gIH0sIGRlcHMpO1xuXG4gIC8vIFdlIHRlbGwgcmVhY3QgdGhhdCBmaXJzdCBtb3VudCBoYXMgcGFzc2VkXG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgZmlyc3RNb3VudFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGZpcnN0TW91bnRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfTtcbiAgfSwgW10pO1xufTsiLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0Jztcbi8qKlxuICogU2FtZSBhcyBSZWFjdC51c2VTdGF0ZSBidXQgYHNldFN0YXRlYCBhY2NlcHQgYGlnbm9yZURlc3Ryb3lgIHBhcmFtIHRvIG5vdCB0byBzZXRTdGF0ZSBhZnRlciBkZXN0cm95ZWQuXG4gKiBXZSBkbyBub3QgbWFrZSB0aGlzIGF1dG8gaXMgdG8gYXZvaWQgcmVhbCBtZW1vcnkgbGVhay5cbiAqIERldmVsb3BlciBzaG91bGQgY29uZmlybSBpdCdzIHNhZmUgdG8gaWdub3JlIHRoZW1zZWx2ZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZVNhZmVTdGF0ZShkZWZhdWx0VmFsdWUpIHtcbiAgdmFyIGRlc3Ryb3lSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUoZGVmYXVsdFZhbHVlKSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICB2YWx1ZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgc2V0VmFsdWUgPSBfUmVhY3QkdXNlU3RhdGUyWzFdO1xuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGRlc3Ryb3lSZWYuY3VycmVudCA9IGZhbHNlO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBkZXN0cm95UmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgZnVuY3Rpb24gc2FmZVNldFN0YXRlKHVwZGF0ZXIsIGlnbm9yZURlc3Ryb3kpIHtcbiAgICBpZiAoaWdub3JlRGVzdHJveSAmJiBkZXN0cm95UmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VmFsdWUodXBkYXRlcik7XG4gIH1cbiAgcmV0dXJuIFt2YWx1ZSwgc2FmZVNldFN0YXRlXTtcbn0iLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCB1c2VFdmVudCBmcm9tIFwiLi91c2VFdmVudFwiO1xuaW1wb3J0IHsgdXNlTGF5b3V0VXBkYXRlRWZmZWN0IH0gZnJvbSBcIi4vdXNlTGF5b3V0RWZmZWN0XCI7XG5pbXBvcnQgdXNlU3RhdGUgZnJvbSBcIi4vdXNlU3RhdGVcIjtcbi8qKiBXZSBvbmx5IHRoaW5rIGB1bmRlZmluZWRgIGlzIGVtcHR5ICovXG5mdW5jdGlvbiBoYXNWYWx1ZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBTaW1pbGFyIHRvIGB1c2VTdGF0ZWAgYnV0IHdpbGwgdXNlIHByb3BzIHZhbHVlIGlmIHByb3ZpZGVkLlxuICogTm90ZSB0aGF0IGludGVybmFsIHVzZSByYy11dGlsIGB1c2VTdGF0ZWAgaG9vay5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlTWVyZ2VkU3RhdGUoZGVmYXVsdFN0YXRlVmFsdWUsIG9wdGlvbikge1xuICB2YXIgX3JlZiA9IG9wdGlvbiB8fCB7fSxcbiAgICBkZWZhdWx0VmFsdWUgPSBfcmVmLmRlZmF1bHRWYWx1ZSxcbiAgICB2YWx1ZSA9IF9yZWYudmFsdWUsXG4gICAgb25DaGFuZ2UgPSBfcmVmLm9uQ2hhbmdlLFxuICAgIHBvc3RTdGF0ZSA9IF9yZWYucG9zdFN0YXRlO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09IEluaXQgPT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIF91c2VTdGF0ZSA9IHVzZVN0YXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChoYXNWYWx1ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChoYXNWYWx1ZShkZWZhdWx0VmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFZhbHVlID09PSAnZnVuY3Rpb24nID8gZGVmYXVsdFZhbHVlKCkgOiBkZWZhdWx0VmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdHlwZW9mIGRlZmF1bHRTdGF0ZVZhbHVlID09PSAnZnVuY3Rpb24nID8gZGVmYXVsdFN0YXRlVmFsdWUoKSA6IGRlZmF1bHRTdGF0ZVZhbHVlO1xuICAgICAgfVxuICAgIH0pLFxuICAgIF91c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfdXNlU3RhdGUsIDIpLFxuICAgIGlubmVyVmFsdWUgPSBfdXNlU3RhdGUyWzBdLFxuICAgIHNldElubmVyVmFsdWUgPSBfdXNlU3RhdGUyWzFdO1xuICB2YXIgbWVyZ2VkVmFsdWUgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiBpbm5lclZhbHVlO1xuICB2YXIgcG9zdE1lcmdlZFZhbHVlID0gcG9zdFN0YXRlID8gcG9zdFN0YXRlKG1lcmdlZFZhbHVlKSA6IG1lcmdlZFZhbHVlO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT0gQ2hhbmdlID09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG9uQ2hhbmdlRm4gPSB1c2VFdmVudChvbkNoYW5nZSk7XG4gIHZhciBfdXNlU3RhdGUzID0gdXNlU3RhdGUoW21lcmdlZFZhbHVlXSksXG4gICAgX3VzZVN0YXRlNCA9IF9zbGljZWRUb0FycmF5KF91c2VTdGF0ZTMsIDIpLFxuICAgIHByZXZWYWx1ZSA9IF91c2VTdGF0ZTRbMF0sXG4gICAgc2V0UHJldlZhbHVlID0gX3VzZVN0YXRlNFsxXTtcbiAgdXNlTGF5b3V0VXBkYXRlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcHJldiA9IHByZXZWYWx1ZVswXTtcbiAgICBpZiAoaW5uZXJWYWx1ZSAhPT0gcHJldikge1xuICAgICAgb25DaGFuZ2VGbihpbm5lclZhbHVlLCBwcmV2KTtcbiAgICB9XG4gIH0sIFtwcmV2VmFsdWVdKTtcblxuICAvLyBTeW5jIHZhbHVlIGJhY2sgdG8gYHVuZGVmaW5lZGAgd2hlbiBpdCBmcm9tIGNvbnRyb2wgdG8gdW4tY29udHJvbFxuICB1c2VMYXlvdXRVcGRhdGVFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmICghaGFzVmFsdWUodmFsdWUpKSB7XG4gICAgICBzZXRJbm5lclZhbHVlKHZhbHVlKTtcbiAgICB9XG4gIH0sIFt2YWx1ZV0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT0gVXBkYXRlID09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHRyaWdnZXJDaGFuZ2UgPSB1c2VFdmVudChmdW5jdGlvbiAodXBkYXRlciwgaWdub3JlRGVzdHJveSkge1xuICAgIHNldElubmVyVmFsdWUodXBkYXRlciwgaWdub3JlRGVzdHJveSk7XG4gICAgc2V0UHJldlZhbHVlKFttZXJnZWRWYWx1ZV0sIGlnbm9yZURlc3Ryb3kpO1xuICB9KTtcbiAgcmV0dXJuIFtwb3N0TWVyZ2VkVmFsdWUsIHRyaWdnZXJDaGFuZ2VdO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gPyBPYmplY3QuYXNzaWduLmJpbmQoKSA6IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcbiAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG4gIHJldHVybiBfZXh0ZW5kcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpIHtcbiAgaWYgKHNvdXJjZSA9PSBudWxsKSByZXR1cm4ge307XG4gIHZhciB0YXJnZXQgPSB7fTtcbiAgdmFyIHNvdXJjZUtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xuICB2YXIga2V5LCBpO1xuICBmb3IgKGkgPSAwOyBpIDwgc291cmNlS2V5cy5sZW5ndGg7IGkrKykge1xuICAgIGtleSA9IHNvdXJjZUtleXNbaV07XG4gICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59IiwiaW1wb3J0IG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2UgZnJvbSBcIi4vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHNvdXJjZSwgZXhjbHVkZWQpIHtcbiAgaWYgKHNvdXJjZSA9PSBudWxsKSByZXR1cm4ge307XG4gIHZhciB0YXJnZXQgPSBvYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlKHNvdXJjZSwgZXhjbHVkZWQpO1xuICB2YXIga2V5LCBpO1xuICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICAgIHZhciBzb3VyY2VTeW1ib2xLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzb3VyY2UpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBzb3VyY2VTeW1ib2xLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBrZXkgPSBzb3VyY2VTeW1ib2xLZXlzW2ldO1xuICAgICAgaWYgKGV4Y2x1ZGVkLmluZGV4T2Yoa2V5KSA+PSAwKSBjb250aW51ZTtcbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHNvdXJjZSwga2V5KSkgY29udGludWU7XG4gICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGFyZ2V0O1xufSIsImltcG9ydCBkZWZpbmVQcm9wZXJ0eSBmcm9tIFwiLi9kZWZpbmVQcm9wZXJ0eS5qc1wiO1xuZnVuY3Rpb24gb3duS2V5cyhvYmplY3QsIGVudW1lcmFibGVPbmx5KSB7XG4gIHZhciBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTtcbiAgaWYgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMpIHtcbiAgICB2YXIgc3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMob2JqZWN0KTtcbiAgICBlbnVtZXJhYmxlT25seSAmJiAoc3ltYm9scyA9IHN5bWJvbHMuZmlsdGVyKGZ1bmN0aW9uIChzeW0pIHtcbiAgICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgc3ltKS5lbnVtZXJhYmxlO1xuICAgIH0pKSwga2V5cy5wdXNoLmFwcGx5KGtleXMsIHN5bWJvbHMpO1xuICB9XG4gIHJldHVybiBrZXlzO1xufVxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX29iamVjdFNwcmVhZDIodGFyZ2V0KSB7XG4gIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIHNvdXJjZSA9IG51bGwgIT0gYXJndW1lbnRzW2ldID8gYXJndW1lbnRzW2ldIDoge307XG4gICAgaSAlIDIgPyBvd25LZXlzKE9iamVjdChzb3VyY2UpLCAhMCkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgc291cmNlW2tleV0pO1xuICAgIH0pIDogT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKHNvdXJjZSkpIDogb3duS2V5cyhPYmplY3Qoc291cmNlKSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Ioc291cmNlLCBrZXkpKTtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gdGFyZ2V0O1xufSIsIi8qKlxuICogQGlnbm9yZVxuICogc29tZSBrZXktY29kZXMgZGVmaW5pdGlvbiBhbmQgdXRpbHMgZnJvbSBjbG9zdXJlLWxpYnJhcnlcbiAqIEBhdXRob3IgeWltaW5naGVAZ21haWwuY29tXG4gKi9cblxudmFyIEtleUNvZGUgPSB7XG4gIC8qKlxuICAgKiBNQUNfRU5URVJcbiAgICovXG4gIE1BQ19FTlRFUjogMyxcbiAgLyoqXG4gICAqIEJBQ0tTUEFDRVxuICAgKi9cbiAgQkFDS1NQQUNFOiA4LFxuICAvKipcbiAgICogVEFCXG4gICAqL1xuICBUQUI6IDksXG4gIC8qKlxuICAgKiBOVU1MT0NLIG9uIEZGL1NhZmFyaSBNYWNcbiAgICovXG4gIE5VTV9DRU5URVI6IDEyLFxuICAvLyBOVU1MT0NLIG9uIEZGL1NhZmFyaSBNYWNcbiAgLyoqXG4gICAqIEVOVEVSXG4gICAqL1xuICBFTlRFUjogMTMsXG4gIC8qKlxuICAgKiBTSElGVFxuICAgKi9cbiAgU0hJRlQ6IDE2LFxuICAvKipcbiAgICogQ1RSTFxuICAgKi9cbiAgQ1RSTDogMTcsXG4gIC8qKlxuICAgKiBBTFRcbiAgICovXG4gIEFMVDogMTgsXG4gIC8qKlxuICAgKiBQQVVTRVxuICAgKi9cbiAgUEFVU0U6IDE5LFxuICAvKipcbiAgICogQ0FQU19MT0NLXG4gICAqL1xuICBDQVBTX0xPQ0s6IDIwLFxuICAvKipcbiAgICogRVNDXG4gICAqL1xuICBFU0M6IDI3LFxuICAvKipcbiAgICogU1BBQ0VcbiAgICovXG4gIFNQQUNFOiAzMixcbiAgLyoqXG4gICAqIFBBR0VfVVBcbiAgICovXG4gIFBBR0VfVVA6IDMzLFxuICAvLyBhbHNvIE5VTV9OT1JUSF9FQVNUXG4gIC8qKlxuICAgKiBQQUdFX0RPV05cbiAgICovXG4gIFBBR0VfRE9XTjogMzQsXG4gIC8vIGFsc28gTlVNX1NPVVRIX0VBU1RcbiAgLyoqXG4gICAqIEVORFxuICAgKi9cbiAgRU5EOiAzNSxcbiAgLy8gYWxzbyBOVU1fU09VVEhfV0VTVFxuICAvKipcbiAgICogSE9NRVxuICAgKi9cbiAgSE9NRTogMzYsXG4gIC8vIGFsc28gTlVNX05PUlRIX1dFU1RcbiAgLyoqXG4gICAqIExFRlRcbiAgICovXG4gIExFRlQ6IDM3LFxuICAvLyBhbHNvIE5VTV9XRVNUXG4gIC8qKlxuICAgKiBVUFxuICAgKi9cbiAgVVA6IDM4LFxuICAvLyBhbHNvIE5VTV9OT1JUSFxuICAvKipcbiAgICogUklHSFRcbiAgICovXG4gIFJJR0hUOiAzOSxcbiAgLy8gYWxzbyBOVU1fRUFTVFxuICAvKipcbiAgICogRE9XTlxuICAgKi9cbiAgRE9XTjogNDAsXG4gIC8vIGFsc28gTlVNX1NPVVRIXG4gIC8qKlxuICAgKiBQUklOVF9TQ1JFRU5cbiAgICovXG4gIFBSSU5UX1NDUkVFTjogNDQsXG4gIC8qKlxuICAgKiBJTlNFUlRcbiAgICovXG4gIElOU0VSVDogNDUsXG4gIC8vIGFsc28gTlVNX0lOU0VSVFxuICAvKipcbiAgICogREVMRVRFXG4gICAqL1xuICBERUxFVEU6IDQ2LFxuICAvLyBhbHNvIE5VTV9ERUxFVEVcbiAgLyoqXG4gICAqIFpFUk9cbiAgICovXG4gIFpFUk86IDQ4LFxuICAvKipcbiAgICogT05FXG4gICAqL1xuICBPTkU6IDQ5LFxuICAvKipcbiAgICogVFdPXG4gICAqL1xuICBUV086IDUwLFxuICAvKipcbiAgICogVEhSRUVcbiAgICovXG4gIFRIUkVFOiA1MSxcbiAgLyoqXG4gICAqIEZPVVJcbiAgICovXG4gIEZPVVI6IDUyLFxuICAvKipcbiAgICogRklWRVxuICAgKi9cbiAgRklWRTogNTMsXG4gIC8qKlxuICAgKiBTSVhcbiAgICovXG4gIFNJWDogNTQsXG4gIC8qKlxuICAgKiBTRVZFTlxuICAgKi9cbiAgU0VWRU46IDU1LFxuICAvKipcbiAgICogRUlHSFRcbiAgICovXG4gIEVJR0hUOiA1NixcbiAgLyoqXG4gICAqIE5JTkVcbiAgICovXG4gIE5JTkU6IDU3LFxuICAvKipcbiAgICogUVVFU1RJT05fTUFSS1xuICAgKi9cbiAgUVVFU1RJT05fTUFSSzogNjMsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogQVxuICAgKi9cbiAgQTogNjUsXG4gIC8qKlxuICAgKiBCXG4gICAqL1xuICBCOiA2NixcbiAgLyoqXG4gICAqIENcbiAgICovXG4gIEM6IDY3LFxuICAvKipcbiAgICogRFxuICAgKi9cbiAgRDogNjgsXG4gIC8qKlxuICAgKiBFXG4gICAqL1xuICBFOiA2OSxcbiAgLyoqXG4gICAqIEZcbiAgICovXG4gIEY6IDcwLFxuICAvKipcbiAgICogR1xuICAgKi9cbiAgRzogNzEsXG4gIC8qKlxuICAgKiBIXG4gICAqL1xuICBIOiA3MixcbiAgLyoqXG4gICAqIElcbiAgICovXG4gIEk6IDczLFxuICAvKipcbiAgICogSlxuICAgKi9cbiAgSjogNzQsXG4gIC8qKlxuICAgKiBLXG4gICAqL1xuICBLOiA3NSxcbiAgLyoqXG4gICAqIExcbiAgICovXG4gIEw6IDc2LFxuICAvKipcbiAgICogTVxuICAgKi9cbiAgTTogNzcsXG4gIC8qKlxuICAgKiBOXG4gICAqL1xuICBOOiA3OCxcbiAgLyoqXG4gICAqIE9cbiAgICovXG4gIE86IDc5LFxuICAvKipcbiAgICogUFxuICAgKi9cbiAgUDogODAsXG4gIC8qKlxuICAgKiBRXG4gICAqL1xuICBROiA4MSxcbiAgLyoqXG4gICAqIFJcbiAgICovXG4gIFI6IDgyLFxuICAvKipcbiAgICogU1xuICAgKi9cbiAgUzogODMsXG4gIC8qKlxuICAgKiBUXG4gICAqL1xuICBUOiA4NCxcbiAgLyoqXG4gICAqIFVcbiAgICovXG4gIFU6IDg1LFxuICAvKipcbiAgICogVlxuICAgKi9cbiAgVjogODYsXG4gIC8qKlxuICAgKiBXXG4gICAqL1xuICBXOiA4NyxcbiAgLyoqXG4gICAqIFhcbiAgICovXG4gIFg6IDg4LFxuICAvKipcbiAgICogWVxuICAgKi9cbiAgWTogODksXG4gIC8qKlxuICAgKiBaXG4gICAqL1xuICBaOiA5MCxcbiAgLyoqXG4gICAqIE1FVEFcbiAgICovXG4gIE1FVEE6IDkxLFxuICAvLyBXSU5fS0VZX0xFRlRcbiAgLyoqXG4gICAqIFdJTl9LRVlfUklHSFRcbiAgICovXG4gIFdJTl9LRVlfUklHSFQ6IDkyLFxuICAvKipcbiAgICogQ09OVEVYVF9NRU5VXG4gICAqL1xuICBDT05URVhUX01FTlU6IDkzLFxuICAvKipcbiAgICogTlVNX1pFUk9cbiAgICovXG4gIE5VTV9aRVJPOiA5NixcbiAgLyoqXG4gICAqIE5VTV9PTkVcbiAgICovXG4gIE5VTV9PTkU6IDk3LFxuICAvKipcbiAgICogTlVNX1RXT1xuICAgKi9cbiAgTlVNX1RXTzogOTgsXG4gIC8qKlxuICAgKiBOVU1fVEhSRUVcbiAgICovXG4gIE5VTV9USFJFRTogOTksXG4gIC8qKlxuICAgKiBOVU1fRk9VUlxuICAgKi9cbiAgTlVNX0ZPVVI6IDEwMCxcbiAgLyoqXG4gICAqIE5VTV9GSVZFXG4gICAqL1xuICBOVU1fRklWRTogMTAxLFxuICAvKipcbiAgICogTlVNX1NJWFxuICAgKi9cbiAgTlVNX1NJWDogMTAyLFxuICAvKipcbiAgICogTlVNX1NFVkVOXG4gICAqL1xuICBOVU1fU0VWRU46IDEwMyxcbiAgLyoqXG4gICAqIE5VTV9FSUdIVFxuICAgKi9cbiAgTlVNX0VJR0hUOiAxMDQsXG4gIC8qKlxuICAgKiBOVU1fTklORVxuICAgKi9cbiAgTlVNX05JTkU6IDEwNSxcbiAgLyoqXG4gICAqIE5VTV9NVUxUSVBMWVxuICAgKi9cbiAgTlVNX01VTFRJUExZOiAxMDYsXG4gIC8qKlxuICAgKiBOVU1fUExVU1xuICAgKi9cbiAgTlVNX1BMVVM6IDEwNyxcbiAgLyoqXG4gICAqIE5VTV9NSU5VU1xuICAgKi9cbiAgTlVNX01JTlVTOiAxMDksXG4gIC8qKlxuICAgKiBOVU1fUEVSSU9EXG4gICAqL1xuICBOVU1fUEVSSU9EOiAxMTAsXG4gIC8qKlxuICAgKiBOVU1fRElWSVNJT05cbiAgICovXG4gIE5VTV9ESVZJU0lPTjogMTExLFxuICAvKipcbiAgICogRjFcbiAgICovXG4gIEYxOiAxMTIsXG4gIC8qKlxuICAgKiBGMlxuICAgKi9cbiAgRjI6IDExMyxcbiAgLyoqXG4gICAqIEYzXG4gICAqL1xuICBGMzogMTE0LFxuICAvKipcbiAgICogRjRcbiAgICovXG4gIEY0OiAxMTUsXG4gIC8qKlxuICAgKiBGNVxuICAgKi9cbiAgRjU6IDExNixcbiAgLyoqXG4gICAqIEY2XG4gICAqL1xuICBGNjogMTE3LFxuICAvKipcbiAgICogRjdcbiAgICovXG4gIEY3OiAxMTgsXG4gIC8qKlxuICAgKiBGOFxuICAgKi9cbiAgRjg6IDExOSxcbiAgLyoqXG4gICAqIEY5XG4gICAqL1xuICBGOTogMTIwLFxuICAvKipcbiAgICogRjEwXG4gICAqL1xuICBGMTA6IDEyMSxcbiAgLyoqXG4gICAqIEYxMVxuICAgKi9cbiAgRjExOiAxMjIsXG4gIC8qKlxuICAgKiBGMTJcbiAgICovXG4gIEYxMjogMTIzLFxuICAvKipcbiAgICogTlVNTE9DS1xuICAgKi9cbiAgTlVNTE9DSzogMTQ0LFxuICAvKipcbiAgICogU0VNSUNPTE9OXG4gICAqL1xuICBTRU1JQ09MT046IDE4NixcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBEQVNIXG4gICAqL1xuICBEQVNIOiAxODksXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogRVFVQUxTXG4gICAqL1xuICBFUVVBTFM6IDE4NyxcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBDT01NQVxuICAgKi9cbiAgQ09NTUE6IDE4OCxcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBQRVJJT0RcbiAgICovXG4gIFBFUklPRDogMTkwLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIFNMQVNIXG4gICAqL1xuICBTTEFTSDogMTkxLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIEFQT1NUUk9QSEVcbiAgICovXG4gIEFQT1NUUk9QSEU6IDE5MixcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBTSU5HTEVfUVVPVEVcbiAgICovXG4gIFNJTkdMRV9RVU9URTogMjIyLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIE9QRU5fU1FVQVJFX0JSQUNLRVRcbiAgICovXG4gIE9QRU5fU1FVQVJFX0JSQUNLRVQ6IDIxOSxcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBCQUNLU0xBU0hcbiAgICovXG4gIEJBQ0tTTEFTSDogMjIwLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIENMT1NFX1NRVUFSRV9CUkFDS0VUXG4gICAqL1xuICBDTE9TRV9TUVVBUkVfQlJBQ0tFVDogMjIxLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIFdJTl9LRVlcbiAgICovXG4gIFdJTl9LRVk6IDIyNCxcbiAgLyoqXG4gICAqIE1BQ19GRl9NRVRBXG4gICAqL1xuICBNQUNfRkZfTUVUQTogMjI0LFxuICAvLyBGaXJlZm94IChHZWNrbykgZmlyZXMgdGhpcyBmb3IgdGhlIG1ldGEga2V5IGluc3RlYWQgb2YgOTFcbiAgLyoqXG4gICAqIFdJTl9JTUVcbiAgICovXG4gIFdJTl9JTUU6IDIyOSxcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09IEZ1bmN0aW9uID09PT09PT09PT09PT09PT09PT09PT09PVxuICAvKipcbiAgICogd2hldGhlciB0ZXh0IGFuZCBtb2RpZmllZCBrZXkgaXMgZW50ZXJlZCBhdCB0aGUgc2FtZSB0aW1lLlxuICAgKi9cbiAgaXNUZXh0TW9kaWZ5aW5nS2V5RXZlbnQ6IGZ1bmN0aW9uIGlzVGV4dE1vZGlmeWluZ0tleUV2ZW50KGUpIHtcbiAgICB2YXIga2V5Q29kZSA9IGUua2V5Q29kZTtcbiAgICBpZiAoZS5hbHRLZXkgJiYgIWUuY3RybEtleSB8fCBlLm1ldGFLZXkgfHxcbiAgICAvLyBGdW5jdGlvbiBrZXlzIGRvbid0IGdlbmVyYXRlIHRleHRcbiAgICBrZXlDb2RlID49IEtleUNvZGUuRjEgJiYga2V5Q29kZSA8PSBLZXlDb2RlLkYxMikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFRoZSBmb2xsb3dpbmcga2V5cyBhcmUgcXVpdGUgaGFybWxlc3MsIGV2ZW4gaW4gY29tYmluYXRpb24gd2l0aFxuICAgIC8vIENUUkwsIEFMVCBvciBTSElGVC5cbiAgICBzd2l0Y2ggKGtleUNvZGUpIHtcbiAgICAgIGNhc2UgS2V5Q29kZS5BTFQ6XG4gICAgICBjYXNlIEtleUNvZGUuQ0FQU19MT0NLOlxuICAgICAgY2FzZSBLZXlDb2RlLkNPTlRFWFRfTUVOVTpcbiAgICAgIGNhc2UgS2V5Q29kZS5DVFJMOlxuICAgICAgY2FzZSBLZXlDb2RlLkRPV046XG4gICAgICBjYXNlIEtleUNvZGUuRU5EOlxuICAgICAgY2FzZSBLZXlDb2RlLkVTQzpcbiAgICAgIGNhc2UgS2V5Q29kZS5IT01FOlxuICAgICAgY2FzZSBLZXlDb2RlLklOU0VSVDpcbiAgICAgIGNhc2UgS2V5Q29kZS5MRUZUOlxuICAgICAgY2FzZSBLZXlDb2RlLk1BQ19GRl9NRVRBOlxuICAgICAgY2FzZSBLZXlDb2RlLk1FVEE6XG4gICAgICBjYXNlIEtleUNvZGUuTlVNTE9DSzpcbiAgICAgIGNhc2UgS2V5Q29kZS5OVU1fQ0VOVEVSOlxuICAgICAgY2FzZSBLZXlDb2RlLlBBR0VfRE9XTjpcbiAgICAgIGNhc2UgS2V5Q29kZS5QQUdFX1VQOlxuICAgICAgY2FzZSBLZXlDb2RlLlBBVVNFOlxuICAgICAgY2FzZSBLZXlDb2RlLlBSSU5UX1NDUkVFTjpcbiAgICAgIGNhc2UgS2V5Q29kZS5SSUdIVDpcbiAgICAgIGNhc2UgS2V5Q29kZS5TSElGVDpcbiAgICAgIGNhc2UgS2V5Q29kZS5VUDpcbiAgICAgIGNhc2UgS2V5Q29kZS5XSU5fS0VZOlxuICAgICAgY2FzZSBLZXlDb2RlLldJTl9LRVlfUklHSFQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSxcbiAgLyoqXG4gICAqIHdoZXRoZXIgY2hhcmFjdGVyIGlzIGVudGVyZWQuXG4gICAqL1xuICBpc0NoYXJhY3RlcktleTogZnVuY3Rpb24gaXNDaGFyYWN0ZXJLZXkoa2V5Q29kZSkge1xuICAgIGlmIChrZXlDb2RlID49IEtleUNvZGUuWkVSTyAmJiBrZXlDb2RlIDw9IEtleUNvZGUuTklORSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChrZXlDb2RlID49IEtleUNvZGUuTlVNX1pFUk8gJiYga2V5Q29kZSA8PSBLZXlDb2RlLk5VTV9NVUxUSVBMWSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChrZXlDb2RlID49IEtleUNvZGUuQSAmJiBrZXlDb2RlIDw9IEtleUNvZGUuWikge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gU2FmYXJpIHNlbmRzIHplcm8ga2V5IGNvZGUgZm9yIG5vbi1sYXRpbiBjaGFyYWN0ZXJzLlxuICAgIGlmICh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKCdXZWJLaXQnKSAhPT0gLTEgJiYga2V5Q29kZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHN3aXRjaCAoa2V5Q29kZSkge1xuICAgICAgY2FzZSBLZXlDb2RlLlNQQUNFOlxuICAgICAgY2FzZSBLZXlDb2RlLlFVRVNUSU9OX01BUks6XG4gICAgICBjYXNlIEtleUNvZGUuTlVNX1BMVVM6XG4gICAgICBjYXNlIEtleUNvZGUuTlVNX01JTlVTOlxuICAgICAgY2FzZSBLZXlDb2RlLk5VTV9QRVJJT0Q6XG4gICAgICBjYXNlIEtleUNvZGUuTlVNX0RJVklTSU9OOlxuICAgICAgY2FzZSBLZXlDb2RlLlNFTUlDT0xPTjpcbiAgICAgIGNhc2UgS2V5Q29kZS5EQVNIOlxuICAgICAgY2FzZSBLZXlDb2RlLkVRVUFMUzpcbiAgICAgIGNhc2UgS2V5Q29kZS5DT01NQTpcbiAgICAgIGNhc2UgS2V5Q29kZS5QRVJJT0Q6XG4gICAgICBjYXNlIEtleUNvZGUuU0xBU0g6XG4gICAgICBjYXNlIEtleUNvZGUuQVBPU1RST1BIRTpcbiAgICAgIGNhc2UgS2V5Q29kZS5TSU5HTEVfUVVPVEU6XG4gICAgICBjYXNlIEtleUNvZGUuT1BFTl9TUVVBUkVfQlJBQ0tFVDpcbiAgICAgIGNhc2UgS2V5Q29kZS5CQUNLU0xBU0g6XG4gICAgICBjYXNlIEtleUNvZGUuQ0xPU0VfU1FVQVJFX0JSQUNLRVQ6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufTtcbmV4cG9ydCBkZWZhdWx0IEtleUNvZGU7IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xudmFyIFNsaWRlckNvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7XG4gIG1pbjogMCxcbiAgbWF4OiAwLFxuICBkaXJlY3Rpb246ICdsdHInLFxuICBzdGVwOiAxLFxuICBpbmNsdWRlZFN0YXJ0OiAwLFxuICBpbmNsdWRlZEVuZDogMCxcbiAgdGFiSW5kZXg6IDAsXG4gIGtleWJvYXJkOiB0cnVlXG59KTtcbmV4cG9ydCBkZWZhdWx0IFNsaWRlckNvbnRleHQ7IiwiZXhwb3J0IGZ1bmN0aW9uIGdldE9mZnNldCh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgcmV0dXJuICh2YWx1ZSAtIG1pbikgLyAobWF4IC0gbWluKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXJlY3Rpb25TdHlsZShkaXJlY3Rpb24sIHZhbHVlLCBtaW4sIG1heCkge1xuICB2YXIgb2Zmc2V0ID0gZ2V0T2Zmc2V0KHZhbHVlLCBtaW4sIG1heCk7XG4gIHZhciBwb3NpdGlvblN0eWxlID0ge307XG4gIHN3aXRjaCAoZGlyZWN0aW9uKSB7XG4gICAgY2FzZSAncnRsJzpcbiAgICAgIHBvc2l0aW9uU3R5bGUucmlnaHQgPSBcIlwiLmNvbmNhdChvZmZzZXQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZVgoNTAlKSc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdidHQnOlxuICAgICAgcG9zaXRpb25TdHlsZS5ib3R0b20gPSBcIlwiLmNvbmNhdChvZmZzZXQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZVkoNTAlKSc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0dGInOlxuICAgICAgcG9zaXRpb25TdHlsZS50b3AgPSBcIlwiLmNvbmNhdChvZmZzZXQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZVkoLTUwJSknO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHBvc2l0aW9uU3R5bGUubGVmdCA9IFwiXCIuY29uY2F0KG9mZnNldCAqIDEwMCwgXCIlXCIpO1xuICAgICAgcG9zaXRpb25TdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgtNTAlKSc7XG4gICAgICBicmVhaztcbiAgfVxuICByZXR1cm4gcG9zaXRpb25TdHlsZTtcbn1cbi8qKiBSZXR1cm4gaW5kZXggdmFsdWUgaWYgaXMgbGlzdCBvciByZXR1cm4gdmFsdWUgZGlyZWN0bHkgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRJbmRleCh2YWx1ZSwgaW5kZXgpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWVbaW5kZXhdIDogdmFsdWU7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbmltcG9ydCBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzXCI7XG52YXIgX2V4Y2x1ZGVkID0gW1wicHJlZml4Q2xzXCIsIFwidmFsdWVcIiwgXCJ2YWx1ZUluZGV4XCIsIFwib25TdGFydE1vdmVcIiwgXCJzdHlsZVwiLCBcInJlbmRlclwiLCBcImRyYWdnaW5nXCIsIFwib25PZmZzZXRDaGFuZ2VcIl07XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBLZXlDb2RlIGZyb20gXCJyYy11dGlsL2VzL0tleUNvZGVcIjtcbmltcG9ydCBTbGlkZXJDb250ZXh0IGZyb20gJy4uL2NvbnRleHQnO1xuaW1wb3J0IHsgZ2V0RGlyZWN0aW9uU3R5bGUsIGdldEluZGV4IH0gZnJvbSAnLi4vdXRpbCc7XG52YXIgSGFuZGxlID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgdmFyIF9jbGFzc05hbWVzLCBfZ2V0SW5kZXg7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgdmFsdWUgPSBwcm9wcy52YWx1ZSxcbiAgICB2YWx1ZUluZGV4ID0gcHJvcHMudmFsdWVJbmRleCxcbiAgICBvblN0YXJ0TW92ZSA9IHByb3BzLm9uU3RhcnRNb3ZlLFxuICAgIHN0eWxlID0gcHJvcHMuc3R5bGUsXG4gICAgcmVuZGVyID0gcHJvcHMucmVuZGVyLFxuICAgIGRyYWdnaW5nID0gcHJvcHMuZHJhZ2dpbmcsXG4gICAgb25PZmZzZXRDaGFuZ2UgPSBwcm9wcy5vbk9mZnNldENoYW5nZSxcbiAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIF9leGNsdWRlZCk7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoU2xpZGVyQ29udGV4dCksXG4gICAgbWluID0gX1JlYWN0JHVzZUNvbnRleHQubWluLFxuICAgIG1heCA9IF9SZWFjdCR1c2VDb250ZXh0Lm1heCxcbiAgICBkaXJlY3Rpb24gPSBfUmVhY3QkdXNlQ29udGV4dC5kaXJlY3Rpb24sXG4gICAgZGlzYWJsZWQgPSBfUmVhY3QkdXNlQ29udGV4dC5kaXNhYmxlZCxcbiAgICBrZXlib2FyZCA9IF9SZWFjdCR1c2VDb250ZXh0LmtleWJvYXJkLFxuICAgIHJhbmdlID0gX1JlYWN0JHVzZUNvbnRleHQucmFuZ2UsXG4gICAgdGFiSW5kZXggPSBfUmVhY3QkdXNlQ29udGV4dC50YWJJbmRleCxcbiAgICBhcmlhTGFiZWxGb3JIYW5kbGUgPSBfUmVhY3QkdXNlQ29udGV4dC5hcmlhTGFiZWxGb3JIYW5kbGUsXG4gICAgYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGUgPSBfUmVhY3QkdXNlQ29udGV4dC5hcmlhTGFiZWxsZWRCeUZvckhhbmRsZSxcbiAgICBhcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlID0gX1JlYWN0JHVzZUNvbnRleHQuYXJpYVZhbHVlVGV4dEZvcm1hdHRlckZvckhhbmRsZTtcbiAgdmFyIGhhbmRsZVByZWZpeENscyA9IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItaGFuZGxlXCIpO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09IEV2ZW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBvbkludGVybmFsU3RhcnRNb3ZlID0gZnVuY3Rpb24gb25JbnRlcm5hbFN0YXJ0TW92ZShlKSB7XG4gICAgaWYgKCFkaXNhYmxlZCkge1xuICAgICAgb25TdGFydE1vdmUoZSwgdmFsdWVJbmRleCk7XG4gICAgfVxuICB9O1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gS2V5Ym9hcmQgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBvbktleURvd24gPSBmdW5jdGlvbiBvbktleURvd24oZSkge1xuICAgIGlmICghZGlzYWJsZWQgJiYga2V5Ym9hcmQpIHtcbiAgICAgIHZhciBvZmZzZXQgPSBudWxsO1xuICAgICAgLy8gQ2hhbmdlIHRoZSB2YWx1ZVxuICAgICAgc3dpdGNoIChlLndoaWNoIHx8IGUua2V5Q29kZSkge1xuICAgICAgICBjYXNlIEtleUNvZGUuTEVGVDpcbiAgICAgICAgICBvZmZzZXQgPSBkaXJlY3Rpb24gPT09ICdsdHInIHx8IGRpcmVjdGlvbiA9PT0gJ2J0dCcgPyAtMSA6IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgS2V5Q29kZS5SSUdIVDpcbiAgICAgICAgICBvZmZzZXQgPSBkaXJlY3Rpb24gPT09ICdsdHInIHx8IGRpcmVjdGlvbiA9PT0gJ2J0dCcgPyAxIDogLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIFVwIGlzIHBsdXNcbiAgICAgICAgY2FzZSBLZXlDb2RlLlVQOlxuICAgICAgICAgIG9mZnNldCA9IGRpcmVjdGlvbiAhPT0gJ3R0YicgPyAxIDogLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIERvd24gaXMgbWludXNcbiAgICAgICAgY2FzZSBLZXlDb2RlLkRPV046XG4gICAgICAgICAgb2Zmc2V0ID0gZGlyZWN0aW9uICE9PSAndHRiJyA/IC0xIDogMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBLZXlDb2RlLkhPTUU6XG4gICAgICAgICAgb2Zmc2V0ID0gJ21pbic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgS2V5Q29kZS5FTkQ6XG4gICAgICAgICAgb2Zmc2V0ID0gJ21heCc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgS2V5Q29kZS5QQUdFX1VQOlxuICAgICAgICAgIG9mZnNldCA9IDI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgS2V5Q29kZS5QQUdFX0RPV046XG4gICAgICAgICAgb2Zmc2V0ID0gLTI7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAob2Zmc2V0ICE9PSBudWxsKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgb25PZmZzZXRDaGFuZ2Uob2Zmc2V0LCB2YWx1ZUluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gT2Zmc2V0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHBvc2l0aW9uU3R5bGUgPSBnZXREaXJlY3Rpb25TdHlsZShkaXJlY3Rpb24sIHZhbHVlLCBtaW4sIG1heCk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGhhbmRsZU5vZGUgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCBfZXh0ZW5kcyh7XG4gICAgcmVmOiByZWYsXG4gICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKGhhbmRsZVByZWZpeENscywgKF9jbGFzc05hbWVzID0ge30sIF9kZWZpbmVQcm9wZXJ0eShfY2xhc3NOYW1lcywgXCJcIi5jb25jYXQoaGFuZGxlUHJlZml4Q2xzLCBcIi1cIikuY29uY2F0KHZhbHVlSW5kZXggKyAxKSwgcmFuZ2UpLCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIFwiXCIuY29uY2F0KGhhbmRsZVByZWZpeENscywgXCItZHJhZ2dpbmdcIiksIGRyYWdnaW5nKSwgX2NsYXNzTmFtZXMpKSxcbiAgICBzdHlsZTogX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBwb3NpdGlvblN0eWxlKSwgc3R5bGUpLFxuICAgIG9uTW91c2VEb3duOiBvbkludGVybmFsU3RhcnRNb3ZlLFxuICAgIG9uVG91Y2hTdGFydDogb25JbnRlcm5hbFN0YXJ0TW92ZSxcbiAgICBvbktleURvd246IG9uS2V5RG93bixcbiAgICB0YWJJbmRleDogZGlzYWJsZWQgPyBudWxsIDogZ2V0SW5kZXgodGFiSW5kZXgsIHZhbHVlSW5kZXgpLFxuICAgIHJvbGU6IFwic2xpZGVyXCIsXG4gICAgXCJhcmlhLXZhbHVlbWluXCI6IG1pbixcbiAgICBcImFyaWEtdmFsdWVtYXhcIjogbWF4LFxuICAgIFwiYXJpYS12YWx1ZW5vd1wiOiB2YWx1ZSxcbiAgICBcImFyaWEtZGlzYWJsZWRcIjogZGlzYWJsZWQsXG4gICAgXCJhcmlhLWxhYmVsXCI6IGdldEluZGV4KGFyaWFMYWJlbEZvckhhbmRsZSwgdmFsdWVJbmRleCksXG4gICAgXCJhcmlhLWxhYmVsbGVkYnlcIjogZ2V0SW5kZXgoYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGUsIHZhbHVlSW5kZXgpLFxuICAgIFwiYXJpYS12YWx1ZXRleHRcIjogKF9nZXRJbmRleCA9IGdldEluZGV4KGFyaWFWYWx1ZVRleHRGb3JtYXR0ZXJGb3JIYW5kbGUsIHZhbHVlSW5kZXgpKSA9PT0gbnVsbCB8fCBfZ2V0SW5kZXggPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9nZXRJbmRleCh2YWx1ZSlcbiAgfSwgcmVzdFByb3BzKSk7XG4gIC8vIEN1c3RvbWl6ZVxuICBpZiAocmVuZGVyKSB7XG4gICAgaGFuZGxlTm9kZSA9IHJlbmRlcihoYW5kbGVOb2RlLCB7XG4gICAgICBpbmRleDogdmFsdWVJbmRleCxcbiAgICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZHJhZ2dpbmc6IGRyYWdnaW5nXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGhhbmRsZU5vZGU7XG59KTtcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIEhhbmRsZS5kaXNwbGF5TmFtZSA9ICdIYW5kbGUnO1xufVxuZXhwb3J0IGRlZmF1bHQgSGFuZGxlOyIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJwcmVmaXhDbHNcIiwgXCJzdHlsZVwiLCBcIm9uU3RhcnRNb3ZlXCIsIFwib25PZmZzZXRDaGFuZ2VcIiwgXCJ2YWx1ZXNcIiwgXCJoYW5kbGVSZW5kZXJcIiwgXCJkcmFnZ2luZ0luZGV4XCJdO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEhhbmRsZSBmcm9tICcuL0hhbmRsZSc7XG5pbXBvcnQgeyBnZXRJbmRleCB9IGZyb20gJy4uL3V0aWwnO1xudmFyIEhhbmRsZXMgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIHN0eWxlID0gcHJvcHMuc3R5bGUsXG4gICAgb25TdGFydE1vdmUgPSBwcm9wcy5vblN0YXJ0TW92ZSxcbiAgICBvbk9mZnNldENoYW5nZSA9IHByb3BzLm9uT2Zmc2V0Q2hhbmdlLFxuICAgIHZhbHVlcyA9IHByb3BzLnZhbHVlcyxcbiAgICBoYW5kbGVSZW5kZXIgPSBwcm9wcy5oYW5kbGVSZW5kZXIsXG4gICAgZHJhZ2dpbmdJbmRleCA9IHByb3BzLmRyYWdnaW5nSW5kZXgsXG4gICAgcmVzdFByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHByb3BzLCBfZXhjbHVkZWQpO1xuICB2YXIgaGFuZGxlc1JlZiA9IFJlYWN0LnVzZVJlZih7fSk7XG4gIFJlYWN0LnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZvY3VzOiBmdW5jdGlvbiBmb2N1cyhpbmRleCkge1xuICAgICAgICB2YXIgX2hhbmRsZXNSZWYkY3VycmVudCRpO1xuICAgICAgICAoX2hhbmRsZXNSZWYkY3VycmVudCRpID0gaGFuZGxlc1JlZi5jdXJyZW50W2luZGV4XSkgPT09IG51bGwgfHwgX2hhbmRsZXNSZWYkY3VycmVudCRpID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfaGFuZGxlc1JlZiRjdXJyZW50JGkuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9KTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0LkZyYWdtZW50LCBudWxsLCB2YWx1ZXMubWFwKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoSGFuZGxlLCBfZXh0ZW5kcyh7XG4gICAgICByZWY6IGZ1bmN0aW9uIHJlZihub2RlKSB7XG4gICAgICAgIGlmICghbm9kZSkge1xuICAgICAgICAgIGRlbGV0ZSBoYW5kbGVzUmVmLmN1cnJlbnRbaW5kZXhdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhhbmRsZXNSZWYuY3VycmVudFtpbmRleF0gPSBub2RlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZHJhZ2dpbmc6IGRyYWdnaW5nSW5kZXggPT09IGluZGV4LFxuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICBzdHlsZTogZ2V0SW5kZXgoc3R5bGUsIGluZGV4KSxcbiAgICAgIGtleTogaW5kZXgsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICB2YWx1ZUluZGV4OiBpbmRleCxcbiAgICAgIG9uU3RhcnRNb3ZlOiBvblN0YXJ0TW92ZSxcbiAgICAgIG9uT2Zmc2V0Q2hhbmdlOiBvbk9mZnNldENoYW5nZSxcbiAgICAgIHJlbmRlcjogaGFuZGxlUmVuZGVyXG4gICAgfSwgcmVzdFByb3BzKSk7XG4gIH0pKTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgSGFuZGxlcy5kaXNwbGF5TmFtZSA9ICdIYW5kbGVzJztcbn1cbmV4cG9ydCBkZWZhdWx0IEhhbmRsZXM7IiwiaW1wb3J0IF90b0NvbnN1bWFibGVBcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXlcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZnVuY3Rpb24gZ2V0UG9zaXRpb24oZSkge1xuICB2YXIgb2JqID0gJ3RvdWNoZXMnIGluIGUgPyBlLnRvdWNoZXNbMF0gOiBlO1xuICByZXR1cm4ge1xuICAgIHBhZ2VYOiBvYmoucGFnZVgsXG4gICAgcGFnZVk6IG9iai5wYWdlWVxuICB9O1xufVxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlRHJhZyhjb250YWluZXJSZWYsIGRpcmVjdGlvbiwgcmF3VmFsdWVzLCBtaW4sIG1heCwgZm9ybWF0VmFsdWUsIHRyaWdnZXJDaGFuZ2UsIGZpbmlzaENoYW5nZSwgb2Zmc2V0VmFsdWVzKSB7XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZShudWxsKSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICBkcmFnZ2luZ1ZhbHVlID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXREcmFnZ2luZ1ZhbHVlID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZTMgPSBSZWFjdC51c2VTdGF0ZSgtMSksXG4gICAgX1JlYWN0JHVzZVN0YXRlNCA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTMsIDIpLFxuICAgIGRyYWdnaW5nSW5kZXggPSBfUmVhY3QkdXNlU3RhdGU0WzBdLFxuICAgIHNldERyYWdnaW5nSW5kZXggPSBfUmVhY3QkdXNlU3RhdGU0WzFdO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlNSA9IFJlYWN0LnVzZVN0YXRlKHJhd1ZhbHVlcyksXG4gICAgX1JlYWN0JHVzZVN0YXRlNiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTUsIDIpLFxuICAgIGNhY2hlVmFsdWVzID0gX1JlYWN0JHVzZVN0YXRlNlswXSxcbiAgICBzZXRDYWNoZVZhbHVlcyA9IF9SZWFjdCR1c2VTdGF0ZTZbMV07XG4gIHZhciBfUmVhY3QkdXNlU3RhdGU3ID0gUmVhY3QudXNlU3RhdGUocmF3VmFsdWVzKSxcbiAgICBfUmVhY3QkdXNlU3RhdGU4ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlNywgMiksXG4gICAgb3JpZ2luVmFsdWVzID0gX1JlYWN0JHVzZVN0YXRlOFswXSxcbiAgICBzZXRPcmlnaW5WYWx1ZXMgPSBfUmVhY3QkdXNlU3RhdGU4WzFdO1xuICB2YXIgbW91c2VNb3ZlRXZlbnRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIHZhciBtb3VzZVVwRXZlbnRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGRyYWdnaW5nSW5kZXggPT09IC0xKSB7XG4gICAgICBzZXRDYWNoZVZhbHVlcyhyYXdWYWx1ZXMpO1xuICAgIH1cbiAgfSwgW3Jhd1ZhbHVlcywgZHJhZ2dpbmdJbmRleF0pO1xuICAvLyBDbGVhbiB1cCBldmVudFxuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3VzZU1vdmVFdmVudFJlZi5jdXJyZW50KTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBtb3VzZVVwRXZlbnRSZWYuY3VycmVudCk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBtb3VzZU1vdmVFdmVudFJlZi5jdXJyZW50KTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgbW91c2VVcEV2ZW50UmVmLmN1cnJlbnQpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgdmFyIGZsdXNoVmFsdWVzID0gZnVuY3Rpb24gZmx1c2hWYWx1ZXMobmV4dFZhbHVlcywgbmV4dFZhbHVlKSB7XG4gICAgLy8gUGVyZjogT25seSB1cGRhdGUgc3RhdGUgd2hlbiB2YWx1ZSBjaGFuZ2VkXG4gICAgaWYgKGNhY2hlVmFsdWVzLnNvbWUoZnVuY3Rpb24gKHZhbCwgaSkge1xuICAgICAgcmV0dXJuIHZhbCAhPT0gbmV4dFZhbHVlc1tpXTtcbiAgICB9KSkge1xuICAgICAgaWYgKG5leHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNldERyYWdnaW5nVmFsdWUobmV4dFZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHNldENhY2hlVmFsdWVzKG5leHRWYWx1ZXMpO1xuICAgICAgdHJpZ2dlckNoYW5nZShuZXh0VmFsdWVzKTtcbiAgICB9XG4gIH07XG4gIHZhciB1cGRhdGVDYWNoZVZhbHVlID0gZnVuY3Rpb24gdXBkYXRlQ2FjaGVWYWx1ZSh2YWx1ZUluZGV4LCBvZmZzZXRQZXJjZW50KSB7XG4gICAgLy8gQmFzaWMgcG9pbnQgb2Zmc2V0XG4gICAgaWYgKHZhbHVlSW5kZXggPT09IC0xKSB7XG4gICAgICAvLyA+Pj4+IERyYWdnaW5nIG9uIHRoZSB0cmFja1xuICAgICAgdmFyIHN0YXJ0VmFsdWUgPSBvcmlnaW5WYWx1ZXNbMF07XG4gICAgICB2YXIgZW5kVmFsdWUgPSBvcmlnaW5WYWx1ZXNbb3JpZ2luVmFsdWVzLmxlbmd0aCAtIDFdO1xuICAgICAgdmFyIG1heFN0YXJ0T2Zmc2V0ID0gbWluIC0gc3RhcnRWYWx1ZTtcbiAgICAgIHZhciBtYXhFbmRPZmZzZXQgPSBtYXggLSBlbmRWYWx1ZTtcbiAgICAgIC8vIEdldCB2YWxpZCBvZmZzZXRcbiAgICAgIHZhciBvZmZzZXQgPSBvZmZzZXRQZXJjZW50ICogKG1heCAtIG1pbik7XG4gICAgICBvZmZzZXQgPSBNYXRoLm1heChvZmZzZXQsIG1heFN0YXJ0T2Zmc2V0KTtcbiAgICAgIG9mZnNldCA9IE1hdGgubWluKG9mZnNldCwgbWF4RW5kT2Zmc2V0KTtcbiAgICAgIC8vIFVzZSBmaXJzdCB2YWx1ZSB0byByZXZlcnQgYmFjayBvZiB2YWxpZCBvZmZzZXQgKGxpa2Ugc3RlcHMgbWFya3MpXG4gICAgICB2YXIgZm9ybWF0U3RhcnRWYWx1ZSA9IGZvcm1hdFZhbHVlKHN0YXJ0VmFsdWUgKyBvZmZzZXQpO1xuICAgICAgb2Zmc2V0ID0gZm9ybWF0U3RhcnRWYWx1ZSAtIHN0YXJ0VmFsdWU7XG4gICAgICB2YXIgY2xvbmVDYWNoZVZhbHVlcyA9IG9yaWdpblZhbHVlcy5tYXAoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICByZXR1cm4gdmFsICsgb2Zmc2V0O1xuICAgICAgfSk7XG4gICAgICBmbHVzaFZhbHVlcyhjbG9uZUNhY2hlVmFsdWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gPj4+PiBEcmFnZ2luZyBvbiB0aGUgaGFuZGxlXG4gICAgICB2YXIgb2Zmc2V0RGlzdCA9IChtYXggLSBtaW4pICogb2Zmc2V0UGVyY2VudDtcbiAgICAgIC8vIEFsd2F5cyBzdGFydCB3aXRoIHRoZSB2YWx1ZUluZGV4IG9yaWdpbiB2YWx1ZVxuICAgICAgdmFyIGNsb25lVmFsdWVzID0gX3RvQ29uc3VtYWJsZUFycmF5KGNhY2hlVmFsdWVzKTtcbiAgICAgIGNsb25lVmFsdWVzW3ZhbHVlSW5kZXhdID0gb3JpZ2luVmFsdWVzW3ZhbHVlSW5kZXhdO1xuICAgICAgdmFyIG5leHQgPSBvZmZzZXRWYWx1ZXMoY2xvbmVWYWx1ZXMsIG9mZnNldERpc3QsIHZhbHVlSW5kZXgsICdkaXN0Jyk7XG4gICAgICBmbHVzaFZhbHVlcyhuZXh0LnZhbHVlcywgbmV4dC52YWx1ZSk7XG4gICAgfVxuICB9O1xuICAvLyBSZXNvbHZlIGNsb3N1cmVcbiAgdmFyIHVwZGF0ZUNhY2hlVmFsdWVSZWYgPSBSZWFjdC51c2VSZWYodXBkYXRlQ2FjaGVWYWx1ZSk7XG4gIHVwZGF0ZUNhY2hlVmFsdWVSZWYuY3VycmVudCA9IHVwZGF0ZUNhY2hlVmFsdWU7XG4gIHZhciBvblN0YXJ0TW92ZSA9IGZ1bmN0aW9uIG9uU3RhcnRNb3ZlKGUsIHZhbHVlSW5kZXgpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHZhciBvcmlnaW5WYWx1ZSA9IHJhd1ZhbHVlc1t2YWx1ZUluZGV4XTtcbiAgICBzZXREcmFnZ2luZ0luZGV4KHZhbHVlSW5kZXgpO1xuICAgIHNldERyYWdnaW5nVmFsdWUob3JpZ2luVmFsdWUpO1xuICAgIHNldE9yaWdpblZhbHVlcyhyYXdWYWx1ZXMpO1xuICAgIHZhciBfZ2V0UG9zaXRpb24gPSBnZXRQb3NpdGlvbihlKSxcbiAgICAgIHN0YXJ0WCA9IF9nZXRQb3NpdGlvbi5wYWdlWCxcbiAgICAgIHN0YXJ0WSA9IF9nZXRQb3NpdGlvbi5wYWdlWTtcbiAgICAvLyBNb3ZpbmdcbiAgICB2YXIgb25Nb3VzZU1vdmUgPSBmdW5jdGlvbiBvbk1vdXNlTW92ZShldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHZhciBfZ2V0UG9zaXRpb24yID0gZ2V0UG9zaXRpb24oZXZlbnQpLFxuICAgICAgICBtb3ZlWCA9IF9nZXRQb3NpdGlvbjIucGFnZVgsXG4gICAgICAgIG1vdmVZID0gX2dldFBvc2l0aW9uMi5wYWdlWTtcbiAgICAgIHZhciBvZmZzZXRYID0gbW92ZVggLSBzdGFydFg7XG4gICAgICB2YXIgb2Zmc2V0WSA9IG1vdmVZIC0gc3RhcnRZO1xuICAgICAgdmFyIF9jb250YWluZXJSZWYkY3VycmVudCA9IGNvbnRhaW5lclJlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICB3aWR0aCA9IF9jb250YWluZXJSZWYkY3VycmVudC53aWR0aCxcbiAgICAgICAgaGVpZ2h0ID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LmhlaWdodDtcbiAgICAgIHZhciBvZmZTZXRQZXJjZW50O1xuICAgICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgICAgY2FzZSAnYnR0JzpcbiAgICAgICAgICBvZmZTZXRQZXJjZW50ID0gLW9mZnNldFkgLyBoZWlnaHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3R0Yic6XG4gICAgICAgICAgb2ZmU2V0UGVyY2VudCA9IG9mZnNldFkgLyBoZWlnaHQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3J0bCc6XG4gICAgICAgICAgb2ZmU2V0UGVyY2VudCA9IC1vZmZzZXRYIC8gd2lkdGg7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgb2ZmU2V0UGVyY2VudCA9IG9mZnNldFggLyB3aWR0aDtcbiAgICAgIH1cbiAgICAgIHVwZGF0ZUNhY2hlVmFsdWVSZWYuY3VycmVudCh2YWx1ZUluZGV4LCBvZmZTZXRQZXJjZW50KTtcbiAgICB9O1xuICAgIC8vIEVuZFxuICAgIHZhciBvbk1vdXNlVXAgPSBmdW5jdGlvbiBvbk1vdXNlVXAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgb25Nb3VzZVVwKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG9uTW91c2VNb3ZlKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgb25Nb3VzZVVwKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIG9uTW91c2VNb3ZlKTtcbiAgICAgIG1vdXNlTW92ZUV2ZW50UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgbW91c2VVcEV2ZW50UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgc2V0RHJhZ2dpbmdJbmRleCgtMSk7XG4gICAgICBmaW5pc2hDaGFuZ2UoKTtcbiAgICB9O1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvbk1vdXNlVXApO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG9uTW91c2VNb3ZlKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIG9uTW91c2VVcCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgIG1vdXNlTW92ZUV2ZW50UmVmLmN1cnJlbnQgPSBvbk1vdXNlTW92ZTtcbiAgICBtb3VzZVVwRXZlbnRSZWYuY3VycmVudCA9IG9uTW91c2VVcDtcbiAgfTtcbiAgLy8gT25seSByZXR1cm4gY2FjaGUgdmFsdWUgd2hlbiBpdCBtYXBwaW5nIHdpdGggcmF3VmFsdWVzXG4gIHZhciByZXR1cm5WYWx1ZXMgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc291cmNlVmFsdWVzID0gX3RvQ29uc3VtYWJsZUFycmF5KHJhd1ZhbHVlcykuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIHZhciB0YXJnZXRWYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkoY2FjaGVWYWx1ZXMpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgICByZXR1cm4gc291cmNlVmFsdWVzLmV2ZXJ5KGZ1bmN0aW9uICh2YWwsIGluZGV4KSB7XG4gICAgICByZXR1cm4gdmFsID09PSB0YXJnZXRWYWx1ZXNbaW5kZXhdO1xuICAgIH0pID8gY2FjaGVWYWx1ZXMgOiByYXdWYWx1ZXM7XG4gIH0sIFtyYXdWYWx1ZXMsIGNhY2hlVmFsdWVzXSk7XG4gIHJldHVybiBbZHJhZ2dpbmdJbmRleCwgZHJhZ2dpbmdWYWx1ZSwgcmV0dXJuVmFsdWVzLCBvblN0YXJ0TW92ZV07XG59IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5pbXBvcnQgeyBnZXRPZmZzZXQgfSBmcm9tICcuLi91dGlsJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRyYWNrKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICBzdGFydCA9IHByb3BzLnN0YXJ0LFxuICAgIGVuZCA9IHByb3BzLmVuZCxcbiAgICBpbmRleCA9IHByb3BzLmluZGV4LFxuICAgIG9uU3RhcnRNb3ZlID0gcHJvcHMub25TdGFydE1vdmU7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoU2xpZGVyQ29udGV4dCksXG4gICAgZGlyZWN0aW9uID0gX1JlYWN0JHVzZUNvbnRleHQuZGlyZWN0aW9uLFxuICAgIG1pbiA9IF9SZWFjdCR1c2VDb250ZXh0Lm1pbixcbiAgICBtYXggPSBfUmVhY3QkdXNlQ29udGV4dC5tYXgsXG4gICAgZGlzYWJsZWQgPSBfUmVhY3QkdXNlQ29udGV4dC5kaXNhYmxlZCxcbiAgICByYW5nZSA9IF9SZWFjdCR1c2VDb250ZXh0LnJhbmdlO1xuICB2YXIgdHJhY2tQcmVmaXhDbHMgPSBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXRyYWNrXCIpO1xuICB2YXIgb2Zmc2V0U3RhcnQgPSBnZXRPZmZzZXQoc3RhcnQsIG1pbiwgbWF4KTtcbiAgdmFyIG9mZnNldEVuZCA9IGdldE9mZnNldChlbmQsIG1pbiwgbWF4KTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBFdmVudHMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgb25JbnRlcm5hbFN0YXJ0TW92ZSA9IGZ1bmN0aW9uIG9uSW50ZXJuYWxTdGFydE1vdmUoZSkge1xuICAgIGlmICghZGlzYWJsZWQgJiYgb25TdGFydE1vdmUpIHtcbiAgICAgIG9uU3RhcnRNb3ZlKGUsIC0xKTtcbiAgICB9XG4gIH07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHBvc2l0aW9uU3R5bGUgPSB7fTtcbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICBjYXNlICdydGwnOlxuICAgICAgcG9zaXRpb25TdHlsZS5yaWdodCA9IFwiXCIuY29uY2F0KG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBwb3NpdGlvblN0eWxlLndpZHRoID0gXCJcIi5jb25jYXQob2Zmc2V0RW5kICogMTAwIC0gb2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2J0dCc6XG4gICAgICBwb3NpdGlvblN0eWxlLmJvdHRvbSA9IFwiXCIuY29uY2F0KG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBwb3NpdGlvblN0eWxlLmhlaWdodCA9IFwiXCIuY29uY2F0KG9mZnNldEVuZCAqIDEwMCAtIG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0dGInOlxuICAgICAgcG9zaXRpb25TdHlsZS50b3AgPSBcIlwiLmNvbmNhdChvZmZzZXRTdGFydCAqIDEwMCwgXCIlXCIpO1xuICAgICAgcG9zaXRpb25TdHlsZS5oZWlnaHQgPSBcIlwiLmNvbmNhdChvZmZzZXRFbmQgKiAxMDAgLSBvZmZzZXRTdGFydCAqIDEwMCwgXCIlXCIpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHBvc2l0aW9uU3R5bGUubGVmdCA9IFwiXCIuY29uY2F0KG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBwb3NpdGlvblN0eWxlLndpZHRoID0gXCJcIi5jb25jYXQob2Zmc2V0RW5kICogMTAwIC0gb2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgfVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyh0cmFja1ByZWZpeENscywgcmFuZ2UgJiYgXCJcIi5jb25jYXQodHJhY2tQcmVmaXhDbHMsIFwiLVwiKS5jb25jYXQoaW5kZXggKyAxKSksXG4gICAgc3R5bGU6IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgcG9zaXRpb25TdHlsZSksIHN0eWxlKSxcbiAgICBvbk1vdXNlRG93bjogb25JbnRlcm5hbFN0YXJ0TW92ZSxcbiAgICBvblRvdWNoU3RhcnQ6IG9uSW50ZXJuYWxTdGFydE1vdmVcbiAgfSk7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5pbXBvcnQgVHJhY2sgZnJvbSAnLi9UcmFjayc7XG5pbXBvcnQgeyBnZXRJbmRleCB9IGZyb20gJy4uL3V0aWwnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVHJhY2tzKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICB2YWx1ZXMgPSBwcm9wcy52YWx1ZXMsXG4gICAgc3RhcnRQb2ludCA9IHByb3BzLnN0YXJ0UG9pbnQsXG4gICAgb25TdGFydE1vdmUgPSBwcm9wcy5vblN0YXJ0TW92ZTtcbiAgdmFyIF9SZWFjdCR1c2VDb250ZXh0ID0gUmVhY3QudXNlQ29udGV4dChTbGlkZXJDb250ZXh0KSxcbiAgICBpbmNsdWRlZCA9IF9SZWFjdCR1c2VDb250ZXh0LmluY2x1ZGVkLFxuICAgIHJhbmdlID0gX1JlYWN0JHVzZUNvbnRleHQucmFuZ2UsXG4gICAgbWluID0gX1JlYWN0JHVzZUNvbnRleHQubWluO1xuICB2YXIgdHJhY2tMaXN0ID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFyYW5nZSkge1xuICAgICAgLy8gbnVsbCB2YWx1ZSBkbyBub3QgaGF2ZSB0cmFja1xuICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIHN0YXJ0VmFsdWUgPSBzdGFydFBvaW50ICE9PSBudWxsICYmIHN0YXJ0UG9pbnQgIT09IHZvaWQgMCA/IHN0YXJ0UG9pbnQgOiBtaW47XG4gICAgICB2YXIgZW5kVmFsdWUgPSB2YWx1ZXNbMF07XG4gICAgICByZXR1cm4gW3tcbiAgICAgICAgc3RhcnQ6IE1hdGgubWluKHN0YXJ0VmFsdWUsIGVuZFZhbHVlKSxcbiAgICAgICAgZW5kOiBNYXRoLm1heChzdGFydFZhbHVlLCBlbmRWYWx1ZSlcbiAgICAgIH1dO1xuICAgIH1cbiAgICAvLyBNdWx0aXBsZVxuICAgIHZhciBsaXN0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoIC0gMTsgaSArPSAxKSB7XG4gICAgICBsaXN0LnB1c2goe1xuICAgICAgICBzdGFydDogdmFsdWVzW2ldLFxuICAgICAgICBlbmQ6IHZhbHVlc1tpICsgMV1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbGlzdDtcbiAgfSwgW3ZhbHVlcywgcmFuZ2UsIHN0YXJ0UG9pbnQsIG1pbl0pO1xuICByZXR1cm4gaW5jbHVkZWQgPyB0cmFja0xpc3QubWFwKGZ1bmN0aW9uIChfcmVmLCBpbmRleCkge1xuICAgIHZhciBzdGFydCA9IF9yZWYuc3RhcnQsXG4gICAgICBlbmQgPSBfcmVmLmVuZDtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoVHJhY2ssIHtcbiAgICAgIGluZGV4OiBpbmRleCxcbiAgICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgICAgc3R5bGU6IGdldEluZGV4KHN0eWxlLCBpbmRleCksXG4gICAgICBzdGFydDogc3RhcnQsXG4gICAgICBlbmQ6IGVuZCxcbiAgICAgIGtleTogaW5kZXgsXG4gICAgICBvblN0YXJ0TW92ZTogb25TdGFydE1vdmVcbiAgICB9KTtcbiAgfSkgOiBudWxsO1xufSIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgeyBnZXREaXJlY3Rpb25TdHlsZSB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNYXJrKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgIHZhbHVlID0gcHJvcHMudmFsdWUsXG4gICAgX29uQ2xpY2sgPSBwcm9wcy5vbkNsaWNrO1xuICB2YXIgX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KFNsaWRlckNvbnRleHQpLFxuICAgIG1pbiA9IF9SZWFjdCR1c2VDb250ZXh0Lm1pbixcbiAgICBtYXggPSBfUmVhY3QkdXNlQ29udGV4dC5tYXgsXG4gICAgZGlyZWN0aW9uID0gX1JlYWN0JHVzZUNvbnRleHQuZGlyZWN0aW9uLFxuICAgIGluY2x1ZGVkU3RhcnQgPSBfUmVhY3QkdXNlQ29udGV4dC5pbmNsdWRlZFN0YXJ0LFxuICAgIGluY2x1ZGVkRW5kID0gX1JlYWN0JHVzZUNvbnRleHQuaW5jbHVkZWRFbmQsXG4gICAgaW5jbHVkZWQgPSBfUmVhY3QkdXNlQ29udGV4dC5pbmNsdWRlZDtcbiAgdmFyIHRleHRDbHMgPSBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXRleHRcIik7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gT2Zmc2V0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHBvc2l0aW9uU3R5bGUgPSBnZXREaXJlY3Rpb25TdHlsZShkaXJlY3Rpb24sIHZhbHVlLCBtaW4sIG1heCk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwge1xuICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyh0ZXh0Q2xzLCBfZGVmaW5lUHJvcGVydHkoe30sIFwiXCIuY29uY2F0KHRleHRDbHMsIFwiLWFjdGl2ZVwiKSwgaW5jbHVkZWQgJiYgaW5jbHVkZWRTdGFydCA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSBpbmNsdWRlZEVuZCkpLFxuICAgIHN0eWxlOiBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIHBvc2l0aW9uU3R5bGUpLCBzdHlsZSksXG4gICAgb25Nb3VzZURvd246IGZ1bmN0aW9uIG9uTW91c2VEb3duKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcbiAgICBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKCkge1xuICAgICAgX29uQ2xpY2sodmFsdWUpO1xuICAgIH1cbiAgfSwgY2hpbGRyZW4pO1xufSIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBNYXJrIGZyb20gJy4vTWFyayc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNYXJrcyhwcm9wcykge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIG1hcmtzID0gcHJvcHMubWFya3MsXG4gICAgb25DbGljayA9IHByb3BzLm9uQ2xpY2s7XG4gIHZhciBtYXJrUHJlZml4Q2xzID0gXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1tYXJrXCIpO1xuICAvLyBOb3QgcmVuZGVyIG1hcmsgaWYgZW1wdHlcbiAgaWYgKCFtYXJrcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogbWFya1ByZWZpeENsc1xuICB9LCBtYXJrcy5tYXAoZnVuY3Rpb24gKF9yZWYpIHtcbiAgICB2YXIgdmFsdWUgPSBfcmVmLnZhbHVlLFxuICAgICAgc3R5bGUgPSBfcmVmLnN0eWxlLFxuICAgICAgbGFiZWwgPSBfcmVmLmxhYmVsO1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNYXJrLCB7XG4gICAgICBrZXk6IHZhbHVlLFxuICAgICAgcHJlZml4Q2xzOiBtYXJrUHJlZml4Q2xzLFxuICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgb25DbGljazogb25DbGlja1xuICAgIH0sIGxhYmVsKTtcbiAgfSkpO1xufSIsImltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5pbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgeyBnZXREaXJlY3Rpb25TdHlsZSB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEb3QocHJvcHMpIHtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICB2YWx1ZSA9IHByb3BzLnZhbHVlLFxuICAgIHN0eWxlID0gcHJvcHMuc3R5bGUsXG4gICAgYWN0aXZlU3R5bGUgPSBwcm9wcy5hY3RpdmVTdHlsZTtcbiAgdmFyIF9SZWFjdCR1c2VDb250ZXh0ID0gUmVhY3QudXNlQ29udGV4dChTbGlkZXJDb250ZXh0KSxcbiAgICBtaW4gPSBfUmVhY3QkdXNlQ29udGV4dC5taW4sXG4gICAgbWF4ID0gX1JlYWN0JHVzZUNvbnRleHQubWF4LFxuICAgIGRpcmVjdGlvbiA9IF9SZWFjdCR1c2VDb250ZXh0LmRpcmVjdGlvbixcbiAgICBpbmNsdWRlZCA9IF9SZWFjdCR1c2VDb250ZXh0LmluY2x1ZGVkLFxuICAgIGluY2x1ZGVkU3RhcnQgPSBfUmVhY3QkdXNlQ29udGV4dC5pbmNsdWRlZFN0YXJ0LFxuICAgIGluY2x1ZGVkRW5kID0gX1JlYWN0JHVzZUNvbnRleHQuaW5jbHVkZWRFbmQ7XG4gIHZhciBkb3RDbGFzc05hbWUgPSBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWRvdFwiKTtcbiAgdmFyIGFjdGl2ZSA9IGluY2x1ZGVkICYmIGluY2x1ZGVkU3RhcnQgPD0gdmFsdWUgJiYgdmFsdWUgPD0gaW5jbHVkZWRFbmQ7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gT2Zmc2V0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG1lcmdlZFN0eWxlID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBnZXREaXJlY3Rpb25TdHlsZShkaXJlY3Rpb24sIHZhbHVlLCBtaW4sIG1heCkpLCB0eXBlb2Ygc3R5bGUgPT09ICdmdW5jdGlvbicgPyBzdHlsZSh2YWx1ZSkgOiBzdHlsZSk7XG4gIGlmIChhY3RpdmUpIHtcbiAgICBtZXJnZWRTdHlsZSA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgbWVyZ2VkU3R5bGUpLCB0eXBlb2YgYWN0aXZlU3R5bGUgPT09ICdmdW5jdGlvbicgPyBhY3RpdmVTdHlsZSh2YWx1ZSkgOiBhY3RpdmVTdHlsZSk7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7XG4gICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKGRvdENsYXNzTmFtZSwgX2RlZmluZVByb3BlcnR5KHt9LCBcIlwiLmNvbmNhdChkb3RDbGFzc05hbWUsIFwiLWFjdGl2ZVwiKSwgYWN0aXZlKSksXG4gICAgc3R5bGU6IG1lcmdlZFN0eWxlXG4gIH0pO1xufSIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTbGlkZXJDb250ZXh0IGZyb20gJy4uL2NvbnRleHQnO1xuaW1wb3J0IERvdCBmcm9tICcuL0RvdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTdGVwcyhwcm9wcykge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIG1hcmtzID0gcHJvcHMubWFya3MsXG4gICAgZG90cyA9IHByb3BzLmRvdHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICBhY3RpdmVTdHlsZSA9IHByb3BzLmFjdGl2ZVN0eWxlO1xuICB2YXIgX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KFNsaWRlckNvbnRleHQpLFxuICAgIG1pbiA9IF9SZWFjdCR1c2VDb250ZXh0Lm1pbixcbiAgICBtYXggPSBfUmVhY3QkdXNlQ29udGV4dC5tYXgsXG4gICAgc3RlcCA9IF9SZWFjdCR1c2VDb250ZXh0LnN0ZXA7XG4gIHZhciBzdGVwRG90cyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHZhciBkb3RTZXQgPSBuZXcgU2V0KCk7XG4gICAgLy8gQWRkIG1hcmtzXG4gICAgbWFya3MuZm9yRWFjaChmdW5jdGlvbiAobWFyaykge1xuICAgICAgZG90U2V0LmFkZChtYXJrLnZhbHVlKTtcbiAgICB9KTtcbiAgICAvLyBGaWxsIGRvdHNcbiAgICBpZiAoZG90cyAmJiBzdGVwICE9PSBudWxsKSB7XG4gICAgICB2YXIgY3VycmVudCA9IG1pbjtcbiAgICAgIHdoaWxlIChjdXJyZW50IDw9IG1heCkge1xuICAgICAgICBkb3RTZXQuYWRkKGN1cnJlbnQpO1xuICAgICAgICBjdXJyZW50ICs9IHN0ZXA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5mcm9tKGRvdFNldCk7XG4gIH0sIFttaW4sIG1heCwgc3RlcCwgZG90cywgbWFya3NdKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItc3RlcFwiKVxuICB9LCBzdGVwRG90cy5tYXAoZnVuY3Rpb24gKGRvdFZhbHVlKSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KERvdCwge1xuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICBrZXk6IGRvdFZhbHVlLFxuICAgICAgdmFsdWU6IGRvdFZhbHVlLFxuICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgYWN0aXZlU3R5bGU6IGFjdGl2ZVN0eWxlXG4gICAgfSk7XG4gIH0pKTtcbn0iLCJpbXBvcnQgX3RvQ29uc3VtYWJsZUFycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0NvbnN1bWFibGVBcnJheVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlT2Zmc2V0KG1pbiwgbWF4LCBzdGVwLCBtYXJrTGlzdCwgYWxsb3dDcm9zcywgcHVzaGFibGUpIHtcbiAgdmFyIGZvcm1hdFJhbmdlVmFsdWUgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFyIGZvcm1hdE5leHRWYWx1ZSA9IGlzRmluaXRlKHZhbCkgPyB2YWwgOiBtaW47XG4gICAgZm9ybWF0TmV4dFZhbHVlID0gTWF0aC5taW4obWF4LCB2YWwpO1xuICAgIGZvcm1hdE5leHRWYWx1ZSA9IE1hdGgubWF4KG1pbiwgZm9ybWF0TmV4dFZhbHVlKTtcbiAgICByZXR1cm4gZm9ybWF0TmV4dFZhbHVlO1xuICB9LCBbbWluLCBtYXhdKTtcbiAgdmFyIGZvcm1hdFN0ZXBWYWx1ZSA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uICh2YWwpIHtcbiAgICBpZiAoc3RlcCAhPT0gbnVsbCkge1xuICAgICAgdmFyIHN0ZXBWYWx1ZSA9IG1pbiArIE1hdGgucm91bmQoKGZvcm1hdFJhbmdlVmFsdWUodmFsKSAtIG1pbikgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICAvLyBDdXQgbnVtYmVyIGluIGNhc2UgdG8gYmUgbGlrZSAwLjMwMDAwMDAwMDAwMDAwMDA0XG4gICAgICB2YXIgZ2V0RGVjaW1hbCA9IGZ1bmN0aW9uIGdldERlY2ltYWwobnVtKSB7XG4gICAgICAgIHJldHVybiAoU3RyaW5nKG51bSkuc3BsaXQoJy4nKVsxXSB8fCAnJykubGVuZ3RoO1xuICAgICAgfTtcbiAgICAgIHZhciBtYXhEZWNpbWFsID0gTWF0aC5tYXgoZ2V0RGVjaW1hbChzdGVwKSwgZ2V0RGVjaW1hbChtYXgpLCBnZXREZWNpbWFsKG1pbikpO1xuICAgICAgdmFyIGZpeGVkVmFsdWUgPSBOdW1iZXIoc3RlcFZhbHVlLnRvRml4ZWQobWF4RGVjaW1hbCkpO1xuICAgICAgcmV0dXJuIG1pbiA8PSBmaXhlZFZhbHVlICYmIGZpeGVkVmFsdWUgPD0gbWF4ID8gZml4ZWRWYWx1ZSA6IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9LCBbc3RlcCwgbWluLCBtYXgsIGZvcm1hdFJhbmdlVmFsdWVdKTtcbiAgdmFyIGZvcm1hdFZhbHVlID0gUmVhY3QudXNlQ2FsbGJhY2soZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhciBmb3JtYXROZXh0VmFsdWUgPSBmb3JtYXRSYW5nZVZhbHVlKHZhbCk7XG4gICAgLy8gTGlzdCBhbGlnbiB2YWx1ZXNcbiAgICB2YXIgYWxpZ25WYWx1ZXMgPSBtYXJrTGlzdC5tYXAoZnVuY3Rpb24gKG1hcmspIHtcbiAgICAgIHJldHVybiBtYXJrLnZhbHVlO1xuICAgIH0pO1xuICAgIGlmIChzdGVwICE9PSBudWxsKSB7XG4gICAgICBhbGlnblZhbHVlcy5wdXNoKGZvcm1hdFN0ZXBWYWx1ZSh2YWwpKTtcbiAgICB9XG4gICAgLy8gbWluICYgbWF4XG4gICAgYWxpZ25WYWx1ZXMucHVzaChtaW4sIG1heCk7XG4gICAgLy8gQWxpZ24gd2l0aCBtYXJrc1xuICAgIHZhciBjbG9zZVZhbHVlID0gYWxpZ25WYWx1ZXNbMF07XG4gICAgdmFyIGNsb3NlRGlzdCA9IG1heCAtIG1pbjtcbiAgICBhbGlnblZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uIChhbGlnblZhbHVlKSB7XG4gICAgICB2YXIgZGlzdCA9IE1hdGguYWJzKGZvcm1hdE5leHRWYWx1ZSAtIGFsaWduVmFsdWUpO1xuICAgICAgaWYgKGRpc3QgPD0gY2xvc2VEaXN0KSB7XG4gICAgICAgIGNsb3NlVmFsdWUgPSBhbGlnblZhbHVlO1xuICAgICAgICBjbG9zZURpc3QgPSBkaXN0O1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBjbG9zZVZhbHVlO1xuICB9LCBbbWluLCBtYXgsIG1hcmtMaXN0LCBzdGVwLCBmb3JtYXRSYW5nZVZhbHVlLCBmb3JtYXRTdGVwVmFsdWVdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gT2Zmc2V0ID09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFNpbmdsZSBWYWx1ZVxuICB2YXIgb2Zmc2V0VmFsdWUgPSBmdW5jdGlvbiBvZmZzZXRWYWx1ZSh2YWx1ZXMsIG9mZnNldCwgdmFsdWVJbmRleCkge1xuICAgIHZhciBtb2RlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAndW5pdCc7XG4gICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdudW1iZXInKSB7XG4gICAgICB2YXIgbmV4dFZhbHVlO1xuICAgICAgdmFyIG9yaWdpblZhbHVlID0gdmFsdWVzW3ZhbHVlSW5kZXhdO1xuICAgICAgLy8gT25seSB1c2VkIGZvciBgZGlzdGAgbW9kZVxuICAgICAgdmFyIHRhcmdldERpc3RWYWx1ZSA9IG9yaWdpblZhbHVlICsgb2Zmc2V0O1xuICAgICAgLy8gQ29tcGFyZSBuZXh0IHN0ZXAgdmFsdWUgJiBtYXJrIHZhbHVlIHdoaWNoIGlzIGJlc3QgbWF0Y2hcbiAgICAgIHZhciBwb3RlbnRpYWxWYWx1ZXMgPSBbXTtcbiAgICAgIG1hcmtMaXN0LmZvckVhY2goZnVuY3Rpb24gKG1hcmspIHtcbiAgICAgICAgcG90ZW50aWFsVmFsdWVzLnB1c2gobWFyay52YWx1ZSk7XG4gICAgICB9KTtcbiAgICAgIC8vIE1pbiAmIE1heFxuICAgICAgcG90ZW50aWFsVmFsdWVzLnB1c2gobWluLCBtYXgpO1xuICAgICAgLy8gSW4gY2FzZSBvcmlnaW4gdmFsdWUgaXMgYWxpZ24gd2l0aCBtYXJrIGJ1dCBub3Qgd2l0aCBzdGVwXG4gICAgICBwb3RlbnRpYWxWYWx1ZXMucHVzaChmb3JtYXRTdGVwVmFsdWUob3JpZ2luVmFsdWUpKTtcbiAgICAgIC8vIFB1dCBvZmZzZXQgc3RlcCB2YWx1ZSBhbHNvXG4gICAgICB2YXIgc2lnbiA9IG9mZnNldCA+IDAgPyAxIDogLTE7XG4gICAgICBpZiAobW9kZSA9PT0gJ3VuaXQnKSB7XG4gICAgICAgIHBvdGVudGlhbFZhbHVlcy5wdXNoKGZvcm1hdFN0ZXBWYWx1ZShvcmlnaW5WYWx1ZSArIHNpZ24gKiBzdGVwKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwb3RlbnRpYWxWYWx1ZXMucHVzaChmb3JtYXRTdGVwVmFsdWUodGFyZ2V0RGlzdFZhbHVlKSk7XG4gICAgICB9XG4gICAgICAvLyBGaW5kIGNsb3NlIG9uZVxuICAgICAgcG90ZW50aWFsVmFsdWVzID0gcG90ZW50aWFsVmFsdWVzLmZpbHRlcihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIHJldHVybiB2YWwgIT09IG51bGw7XG4gICAgICB9KVxuICAgICAgLy8gUmVtb3ZlIHJldmVyc2UgdmFsdWVcbiAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICByZXR1cm4gb2Zmc2V0IDwgMCA/IHZhbCA8PSBvcmlnaW5WYWx1ZSA6IHZhbCA+PSBvcmlnaW5WYWx1ZTtcbiAgICAgIH0pO1xuICAgICAgaWYgKG1vZGUgPT09ICd1bml0Jykge1xuICAgICAgICAvLyBgdW5pdGAgbW9kZSBjYW4gbm90IGNvbnRhaW4gaXRzZWxmXG4gICAgICAgIHBvdGVudGlhbFZhbHVlcyA9IHBvdGVudGlhbFZhbHVlcy5maWx0ZXIoZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICAgIHJldHVybiB2YWwgIT09IG9yaWdpblZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHZhciBjb21wYXJlVmFsdWUgPSBtb2RlID09PSAndW5pdCcgPyBvcmlnaW5WYWx1ZSA6IHRhcmdldERpc3RWYWx1ZTtcbiAgICAgIG5leHRWYWx1ZSA9IHBvdGVudGlhbFZhbHVlc1swXTtcbiAgICAgIHZhciB2YWx1ZURpc3QgPSBNYXRoLmFicyhuZXh0VmFsdWUgLSBjb21wYXJlVmFsdWUpO1xuICAgICAgcG90ZW50aWFsVmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHBvdGVudGlhbFZhbHVlKSB7XG4gICAgICAgIHZhciBkaXN0ID0gTWF0aC5hYnMocG90ZW50aWFsVmFsdWUgLSBjb21wYXJlVmFsdWUpO1xuICAgICAgICBpZiAoZGlzdCA8IHZhbHVlRGlzdCkge1xuICAgICAgICAgIG5leHRWYWx1ZSA9IHBvdGVudGlhbFZhbHVlO1xuICAgICAgICAgIHZhbHVlRGlzdCA9IGRpc3Q7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gT3V0IG9mIHJhbmdlIHdpbGwgYmFjayB0byByYW5nZVxuICAgICAgaWYgKG5leHRWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBvZmZzZXQgPCAwID8gbWluIDogbWF4O1xuICAgICAgfVxuICAgICAgLy8gYGRpc3RgIG1vZGVcbiAgICAgIGlmIChtb2RlID09PSAnZGlzdCcpIHtcbiAgICAgICAgcmV0dXJuIG5leHRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIC8vIGB1bml0YCBtb2RlIG1heSBuZWVkIGFub3RoZXIgcm91bmRcbiAgICAgIGlmIChNYXRoLmFicyhvZmZzZXQpID4gMSkge1xuICAgICAgICB2YXIgY2xvbmVWYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkodmFsdWVzKTtcbiAgICAgICAgY2xvbmVWYWx1ZXNbdmFsdWVJbmRleF0gPSBuZXh0VmFsdWU7XG4gICAgICAgIHJldHVybiBvZmZzZXRWYWx1ZShjbG9uZVZhbHVlcywgb2Zmc2V0IC0gc2lnbiwgdmFsdWVJbmRleCwgbW9kZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV4dFZhbHVlO1xuICAgIH0gZWxzZSBpZiAob2Zmc2V0ID09PSAnbWluJykge1xuICAgICAgcmV0dXJuIG1pbjtcbiAgICB9IGVsc2UgaWYgKG9mZnNldCA9PT0gJ21heCcpIHtcbiAgICAgIHJldHVybiBtYXg7XG4gICAgfVxuICB9O1xuICAvKiogU2FtZSBhcyBgb2Zmc2V0VmFsdWVgIGJ1dCByZXR1cm4gYGNoYW5nZWRgIG1hcmsgdG8gdGVsbCB2YWx1ZSBjaGFuZ2VkICovXG4gIHZhciBvZmZzZXRDaGFuZ2VkVmFsdWUgPSBmdW5jdGlvbiBvZmZzZXRDaGFuZ2VkVmFsdWUodmFsdWVzLCBvZmZzZXQsIHZhbHVlSW5kZXgpIHtcbiAgICB2YXIgbW9kZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogJ3VuaXQnO1xuICAgIHZhciBvcmlnaW5WYWx1ZSA9IHZhbHVlc1t2YWx1ZUluZGV4XTtcbiAgICB2YXIgbmV4dFZhbHVlID0gb2Zmc2V0VmFsdWUodmFsdWVzLCBvZmZzZXQsIHZhbHVlSW5kZXgsIG1vZGUpO1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogbmV4dFZhbHVlLFxuICAgICAgY2hhbmdlZDogbmV4dFZhbHVlICE9PSBvcmlnaW5WYWx1ZVxuICAgIH07XG4gIH07XG4gIHZhciBuZWVkUHVzaCA9IGZ1bmN0aW9uIG5lZWRQdXNoKGRpc3QpIHtcbiAgICByZXR1cm4gcHVzaGFibGUgPT09IG51bGwgJiYgZGlzdCA9PT0gMCB8fCB0eXBlb2YgcHVzaGFibGUgPT09ICdudW1iZXInICYmIGRpc3QgPCBwdXNoYWJsZTtcbiAgfTtcbiAgLy8gVmFsdWVzXG4gIHZhciBvZmZzZXRWYWx1ZXMgPSBmdW5jdGlvbiBvZmZzZXRWYWx1ZXModmFsdWVzLCBvZmZzZXQsIHZhbHVlSW5kZXgpIHtcbiAgICB2YXIgbW9kZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDogJ3VuaXQnO1xuICAgIHZhciBuZXh0VmFsdWVzID0gdmFsdWVzLm1hcChmb3JtYXRWYWx1ZSk7XG4gICAgdmFyIG9yaWdpblZhbHVlID0gbmV4dFZhbHVlc1t2YWx1ZUluZGV4XTtcbiAgICB2YXIgbmV4dFZhbHVlID0gb2Zmc2V0VmFsdWUobmV4dFZhbHVlcywgb2Zmc2V0LCB2YWx1ZUluZGV4LCBtb2RlKTtcbiAgICBuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdID0gbmV4dFZhbHVlO1xuICAgIGlmIChhbGxvd0Nyb3NzID09PSBmYWxzZSkge1xuICAgICAgLy8gPj4+Pj4gQWxsb3cgQ3Jvc3NcbiAgICAgIHZhciBwdXNoTnVtID0gcHVzaGFibGUgfHwgMDtcbiAgICAgIC8vID09PT09PT09PT09PSBBbGxvd0Nyb3NzID09PT09PT09PT09PT09PVxuICAgICAgaWYgKHZhbHVlSW5kZXggPiAwICYmIG5leHRWYWx1ZXNbdmFsdWVJbmRleCAtIDFdICE9PSBvcmlnaW5WYWx1ZSkge1xuICAgICAgICBuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdID0gTWF0aC5tYXgobmV4dFZhbHVlc1t2YWx1ZUluZGV4XSwgbmV4dFZhbHVlc1t2YWx1ZUluZGV4IC0gMV0gKyBwdXNoTnVtKTtcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZUluZGV4IDwgbmV4dFZhbHVlcy5sZW5ndGggLSAxICYmIG5leHRWYWx1ZXNbdmFsdWVJbmRleCArIDFdICE9PSBvcmlnaW5WYWx1ZSkge1xuICAgICAgICBuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdID0gTWF0aC5taW4obmV4dFZhbHVlc1t2YWx1ZUluZGV4XSwgbmV4dFZhbHVlc1t2YWx1ZUluZGV4ICsgMV0gLSBwdXNoTnVtKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwdXNoYWJsZSA9PT0gJ251bWJlcicgfHwgcHVzaGFibGUgPT09IG51bGwpIHtcbiAgICAgIC8vID4+Pj4+IFB1c2hhYmxlXG4gICAgICAvLyA9PT09PT09PT09PT09PT0gUHVzaCA9PT09PT09PT09PT09PT09PT1cbiAgICAgIC8vID4+Pj4+PiBCYXNpYyBwdXNoXG4gICAgICAvLyBFbmQgdmFsdWVzXG4gICAgICBmb3IgKHZhciBpID0gdmFsdWVJbmRleCArIDE7IGkgPCBuZXh0VmFsdWVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIHZhciBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgd2hpbGUgKG5lZWRQdXNoKG5leHRWYWx1ZXNbaV0gLSBuZXh0VmFsdWVzW2kgLSAxXSkgJiYgY2hhbmdlZCkge1xuICAgICAgICAgIHZhciBfb2Zmc2V0Q2hhbmdlZFZhbHVlID0gb2Zmc2V0Q2hhbmdlZFZhbHVlKG5leHRWYWx1ZXMsIDEsIGkpO1xuICAgICAgICAgIG5leHRWYWx1ZXNbaV0gPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlLnZhbHVlO1xuICAgICAgICAgIGNoYW5nZWQgPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlLmNoYW5nZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIFN0YXJ0IHZhbHVlc1xuICAgICAgZm9yICh2YXIgX2kgPSB2YWx1ZUluZGV4OyBfaSA+IDA7IF9pIC09IDEpIHtcbiAgICAgICAgdmFyIF9jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgd2hpbGUgKG5lZWRQdXNoKG5leHRWYWx1ZXNbX2ldIC0gbmV4dFZhbHVlc1tfaSAtIDFdKSAmJiBfY2hhbmdlZCkge1xuICAgICAgICAgIHZhciBfb2Zmc2V0Q2hhbmdlZFZhbHVlMiA9IG9mZnNldENoYW5nZWRWYWx1ZShuZXh0VmFsdWVzLCAtMSwgX2kgLSAxKTtcbiAgICAgICAgICBuZXh0VmFsdWVzW19pIC0gMV0gPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlMi52YWx1ZTtcbiAgICAgICAgICBfY2hhbmdlZCA9IF9vZmZzZXRDaGFuZ2VkVmFsdWUyLmNoYW5nZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vID4+Pj4+IFJldmVydCBiYWNrIHRvIHNhZmUgcHVzaCByYW5nZVxuICAgICAgLy8gRW5kIHRvIFN0YXJ0XG4gICAgICBmb3IgKHZhciBfaTIgPSBuZXh0VmFsdWVzLmxlbmd0aCAtIDE7IF9pMiA+IDA7IF9pMiAtPSAxKSB7XG4gICAgICAgIHZhciBfY2hhbmdlZDIgPSB0cnVlO1xuICAgICAgICB3aGlsZSAobmVlZFB1c2gobmV4dFZhbHVlc1tfaTJdIC0gbmV4dFZhbHVlc1tfaTIgLSAxXSkgJiYgX2NoYW5nZWQyKSB7XG4gICAgICAgICAgdmFyIF9vZmZzZXRDaGFuZ2VkVmFsdWUzID0gb2Zmc2V0Q2hhbmdlZFZhbHVlKG5leHRWYWx1ZXMsIC0xLCBfaTIgLSAxKTtcbiAgICAgICAgICBuZXh0VmFsdWVzW19pMiAtIDFdID0gX29mZnNldENoYW5nZWRWYWx1ZTMudmFsdWU7XG4gICAgICAgICAgX2NoYW5nZWQyID0gX29mZnNldENoYW5nZWRWYWx1ZTMuY2hhbmdlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gU3RhcnQgdG8gRW5kXG4gICAgICBmb3IgKHZhciBfaTMgPSAwOyBfaTMgPCBuZXh0VmFsdWVzLmxlbmd0aCAtIDE7IF9pMyArPSAxKSB7XG4gICAgICAgIHZhciBfY2hhbmdlZDMgPSB0cnVlO1xuICAgICAgICB3aGlsZSAobmVlZFB1c2gobmV4dFZhbHVlc1tfaTMgKyAxXSAtIG5leHRWYWx1ZXNbX2kzXSkgJiYgX2NoYW5nZWQzKSB7XG4gICAgICAgICAgdmFyIF9vZmZzZXRDaGFuZ2VkVmFsdWU0ID0gb2Zmc2V0Q2hhbmdlZFZhbHVlKG5leHRWYWx1ZXMsIDEsIF9pMyArIDEpO1xuICAgICAgICAgIG5leHRWYWx1ZXNbX2kzICsgMV0gPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlNC52YWx1ZTtcbiAgICAgICAgICBfY2hhbmdlZDMgPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlNC5jaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogbmV4dFZhbHVlc1t2YWx1ZUluZGV4XSxcbiAgICAgIHZhbHVlczogbmV4dFZhbHVlc1xuICAgIH07XG4gIH07XG4gIHJldHVybiBbZm9ybWF0VmFsdWUsIG9mZnNldFZhbHVlc107XG59IiwiaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbmltcG9ydCBfdG9Db25zdW1hYmxlQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5XCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCBfdHlwZW9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2ZcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IGlzRXF1YWwgZnJvbSBcInJjLXV0aWwvZXMvaXNFcXVhbFwiO1xuaW1wb3J0IHVzZU1lcmdlZFN0YXRlIGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZU1lcmdlZFN0YXRlXCI7XG5pbXBvcnQgSGFuZGxlcyBmcm9tICcuL0hhbmRsZXMnO1xuaW1wb3J0IHVzZURyYWcgZnJvbSAnLi9ob29rcy91c2VEcmFnJztcbmltcG9ydCBTbGlkZXJDb250ZXh0IGZyb20gJy4vY29udGV4dCc7XG5pbXBvcnQgVHJhY2tzIGZyb20gJy4vVHJhY2tzJztcbmltcG9ydCBNYXJrcyBmcm9tICcuL01hcmtzJztcbmltcG9ydCBTdGVwcyBmcm9tICcuL1N0ZXBzJztcbmltcG9ydCB1c2VPZmZzZXQgZnJvbSAnLi9ob29rcy91c2VPZmZzZXQnO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSBcInJjLXV0aWwvZXMvd2FybmluZ1wiO1xudmFyIFNsaWRlciA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIChwcm9wcywgcmVmKSB7XG4gIHZhciBfY2xhc3NOYW1lcztcbiAgdmFyIF9wcm9wcyRwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgcHJlZml4Q2xzID0gX3Byb3BzJHByZWZpeENscyA9PT0gdm9pZCAwID8gJ3JjLXNsaWRlcicgOiBfcHJvcHMkcHJlZml4Q2xzLFxuICAgIGNsYXNzTmFtZSA9IHByb3BzLmNsYXNzTmFtZSxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIF9wcm9wcyRkaXNhYmxlZCA9IHByb3BzLmRpc2FibGVkLFxuICAgIGRpc2FibGVkID0gX3Byb3BzJGRpc2FibGVkID09PSB2b2lkIDAgPyBmYWxzZSA6IF9wcm9wcyRkaXNhYmxlZCxcbiAgICBfcHJvcHMka2V5Ym9hcmQgPSBwcm9wcy5rZXlib2FyZCxcbiAgICBrZXlib2FyZCA9IF9wcm9wcyRrZXlib2FyZCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRrZXlib2FyZCxcbiAgICBhdXRvRm9jdXMgPSBwcm9wcy5hdXRvRm9jdXMsXG4gICAgb25Gb2N1cyA9IHByb3BzLm9uRm9jdXMsXG4gICAgb25CbHVyID0gcHJvcHMub25CbHVyLFxuICAgIF9wcm9wcyRtaW4gPSBwcm9wcy5taW4sXG4gICAgbWluID0gX3Byb3BzJG1pbiA9PT0gdm9pZCAwID8gMCA6IF9wcm9wcyRtaW4sXG4gICAgX3Byb3BzJG1heCA9IHByb3BzLm1heCxcbiAgICBtYXggPSBfcHJvcHMkbWF4ID09PSB2b2lkIDAgPyAxMDAgOiBfcHJvcHMkbWF4LFxuICAgIF9wcm9wcyRzdGVwID0gcHJvcHMuc3RlcCxcbiAgICBzdGVwID0gX3Byb3BzJHN0ZXAgPT09IHZvaWQgMCA/IDEgOiBfcHJvcHMkc3RlcCxcbiAgICB2YWx1ZSA9IHByb3BzLnZhbHVlLFxuICAgIGRlZmF1bHRWYWx1ZSA9IHByb3BzLmRlZmF1bHRWYWx1ZSxcbiAgICByYW5nZSA9IHByb3BzLnJhbmdlLFxuICAgIGNvdW50ID0gcHJvcHMuY291bnQsXG4gICAgb25DaGFuZ2UgPSBwcm9wcy5vbkNoYW5nZSxcbiAgICBvbkJlZm9yZUNoYW5nZSA9IHByb3BzLm9uQmVmb3JlQ2hhbmdlLFxuICAgIG9uQWZ0ZXJDaGFuZ2UgPSBwcm9wcy5vbkFmdGVyQ2hhbmdlLFxuICAgIF9wcm9wcyRhbGxvd0Nyb3NzID0gcHJvcHMuYWxsb3dDcm9zcyxcbiAgICBhbGxvd0Nyb3NzID0gX3Byb3BzJGFsbG93Q3Jvc3MgPT09IHZvaWQgMCA/IHRydWUgOiBfcHJvcHMkYWxsb3dDcm9zcyxcbiAgICBfcHJvcHMkcHVzaGFibGUgPSBwcm9wcy5wdXNoYWJsZSxcbiAgICBwdXNoYWJsZSA9IF9wcm9wcyRwdXNoYWJsZSA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcHJvcHMkcHVzaGFibGUsXG4gICAgZHJhZ2dhYmxlVHJhY2sgPSBwcm9wcy5kcmFnZ2FibGVUcmFjayxcbiAgICByZXZlcnNlID0gcHJvcHMucmV2ZXJzZSxcbiAgICB2ZXJ0aWNhbCA9IHByb3BzLnZlcnRpY2FsLFxuICAgIF9wcm9wcyRpbmNsdWRlZCA9IHByb3BzLmluY2x1ZGVkLFxuICAgIGluY2x1ZGVkID0gX3Byb3BzJGluY2x1ZGVkID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJGluY2x1ZGVkLFxuICAgIHN0YXJ0UG9pbnQgPSBwcm9wcy5zdGFydFBvaW50LFxuICAgIHRyYWNrU3R5bGUgPSBwcm9wcy50cmFja1N0eWxlLFxuICAgIGhhbmRsZVN0eWxlID0gcHJvcHMuaGFuZGxlU3R5bGUsXG4gICAgcmFpbFN0eWxlID0gcHJvcHMucmFpbFN0eWxlLFxuICAgIGRvdFN0eWxlID0gcHJvcHMuZG90U3R5bGUsXG4gICAgYWN0aXZlRG90U3R5bGUgPSBwcm9wcy5hY3RpdmVEb3RTdHlsZSxcbiAgICBtYXJrcyA9IHByb3BzLm1hcmtzLFxuICAgIGRvdHMgPSBwcm9wcy5kb3RzLFxuICAgIGhhbmRsZVJlbmRlciA9IHByb3BzLmhhbmRsZVJlbmRlcixcbiAgICBfcHJvcHMkdGFiSW5kZXggPSBwcm9wcy50YWJJbmRleCxcbiAgICB0YWJJbmRleCA9IF9wcm9wcyR0YWJJbmRleCA9PT0gdm9pZCAwID8gMCA6IF9wcm9wcyR0YWJJbmRleCxcbiAgICBhcmlhTGFiZWxGb3JIYW5kbGUgPSBwcm9wcy5hcmlhTGFiZWxGb3JIYW5kbGUsXG4gICAgYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGUgPSBwcm9wcy5hcmlhTGFiZWxsZWRCeUZvckhhbmRsZSxcbiAgICBhcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlID0gcHJvcHMuYXJpYVZhbHVlVGV4dEZvcm1hdHRlckZvckhhbmRsZTtcbiAgdmFyIGhhbmRsZXNSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgdmFyIGNvbnRhaW5lclJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICB2YXIgZGlyZWN0aW9uID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHZlcnRpY2FsKSB7XG4gICAgICByZXR1cm4gcmV2ZXJzZSA/ICd0dGInIDogJ2J0dCc7XG4gICAgfVxuICAgIHJldHVybiByZXZlcnNlID8gJ3J0bCcgOiAnbHRyJztcbiAgfSwgW3JldmVyc2UsIHZlcnRpY2FsXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmFuZ2UgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG1lcmdlZE1pbiA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBpc0Zpbml0ZShtaW4pID8gbWluIDogMDtcbiAgfSwgW21pbl0pO1xuICB2YXIgbWVyZ2VkTWF4ID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGlzRmluaXRlKG1heCkgPyBtYXggOiAxMDA7XG4gIH0sIFttYXhdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU3RlcCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWVyZ2VkU3RlcCA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBzdGVwICE9PSBudWxsICYmIHN0ZXAgPD0gMCA/IDEgOiBzdGVwO1xuICB9LCBbc3RlcF0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBQdXNoID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBtZXJnZWRQdXNoID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHB1c2hhYmxlID09PSB0cnVlKSB7XG4gICAgICByZXR1cm4gbWVyZ2VkU3RlcDtcbiAgICB9XG4gICAgcmV0dXJuIHB1c2hhYmxlID49IDAgPyBwdXNoYWJsZSA6IGZhbHNlO1xuICB9LCBbcHVzaGFibGUsIG1lcmdlZFN0ZXBdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBNYXJrcyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWFya0xpc3QgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG1hcmtzIHx8IHt9KTtcbiAgICByZXR1cm4ga2V5cy5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgdmFyIG1hcmsgPSBtYXJrc1trZXldO1xuICAgICAgdmFyIG1hcmtPYmogPSB7XG4gICAgICAgIHZhbHVlOiBOdW1iZXIoa2V5KVxuICAgICAgfTtcbiAgICAgIGlmIChtYXJrICYmIF90eXBlb2YobWFyaykgPT09ICdvYmplY3QnICYmICEgLyojX19QVVJFX18qL1JlYWN0LmlzVmFsaWRFbGVtZW50KG1hcmspICYmICgnbGFiZWwnIGluIG1hcmsgfHwgJ3N0eWxlJyBpbiBtYXJrKSkge1xuICAgICAgICBtYXJrT2JqLnN0eWxlID0gbWFyay5zdHlsZTtcbiAgICAgICAgbWFya09iai5sYWJlbCA9IG1hcmsubGFiZWw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXJrT2JqLmxhYmVsID0gbWFyaztcbiAgICAgIH1cbiAgICAgIHJldHVybiBtYXJrT2JqO1xuICAgIH0pLmZpbHRlcihmdW5jdGlvbiAoX3JlZikge1xuICAgICAgdmFyIGxhYmVsID0gX3JlZi5sYWJlbDtcbiAgICAgIHJldHVybiBsYWJlbCB8fCB0eXBlb2YgbGFiZWwgPT09ICdudW1iZXInO1xuICAgIH0pLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhLnZhbHVlIC0gYi52YWx1ZTtcbiAgICB9KTtcbiAgfSwgW21hcmtzXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gRm9ybWF0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIF91c2VPZmZzZXQgPSB1c2VPZmZzZXQobWVyZ2VkTWluLCBtZXJnZWRNYXgsIG1lcmdlZFN0ZXAsIG1hcmtMaXN0LCBhbGxvd0Nyb3NzLCBtZXJnZWRQdXNoKSxcbiAgICBfdXNlT2Zmc2V0MiA9IF9zbGljZWRUb0FycmF5KF91c2VPZmZzZXQsIDIpLFxuICAgIGZvcm1hdFZhbHVlID0gX3VzZU9mZnNldDJbMF0sXG4gICAgb2Zmc2V0VmFsdWVzID0gX3VzZU9mZnNldDJbMV07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gVmFsdWVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIF91c2VNZXJnZWRTdGF0ZSA9IHVzZU1lcmdlZFN0YXRlKGRlZmF1bHRWYWx1ZSwge1xuICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfSksXG4gICAgX3VzZU1lcmdlZFN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF91c2VNZXJnZWRTdGF0ZSwgMiksXG4gICAgbWVyZ2VkVmFsdWUgPSBfdXNlTWVyZ2VkU3RhdGUyWzBdLFxuICAgIHNldFZhbHVlID0gX3VzZU1lcmdlZFN0YXRlMlsxXTtcbiAgdmFyIHJhd1ZhbHVlcyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZUxpc3QgPSBtZXJnZWRWYWx1ZSA9PT0gbnVsbCB8fCBtZXJnZWRWYWx1ZSA9PT0gdW5kZWZpbmVkID8gW10gOiBBcnJheS5pc0FycmF5KG1lcmdlZFZhbHVlKSA/IG1lcmdlZFZhbHVlIDogW21lcmdlZFZhbHVlXTtcbiAgICB2YXIgX3ZhbHVlTGlzdCA9IF9zbGljZWRUb0FycmF5KHZhbHVlTGlzdCwgMSksXG4gICAgICBfdmFsdWVMaXN0JCA9IF92YWx1ZUxpc3RbMF0sXG4gICAgICB2YWwwID0gX3ZhbHVlTGlzdCQgPT09IHZvaWQgMCA/IG1lcmdlZE1pbiA6IF92YWx1ZUxpc3QkO1xuICAgIHZhciByZXR1cm5WYWx1ZXMgPSBtZXJnZWRWYWx1ZSA9PT0gbnVsbCA/IFtdIDogW3ZhbDBdO1xuICAgIC8vIEZvcm1hdCBhcyByYW5nZVxuICAgIGlmIChyYW5nZSkge1xuICAgICAgcmV0dXJuVmFsdWVzID0gX3RvQ29uc3VtYWJsZUFycmF5KHZhbHVlTGlzdCk7XG4gICAgICAvLyBXaGVuIGNvdW50IHByb3ZpZGVkIG9yIHZhbHVlIGlzIGB1bmRlZmluZWRgLCB3ZSBmaWxsIHZhbHVlc1xuICAgICAgaWYgKGNvdW50IHx8IG1lcmdlZFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIHBvaW50Q291bnQgPSBjb3VudCA+PSAwID8gY291bnQgKyAxIDogMjtcbiAgICAgICAgcmV0dXJuVmFsdWVzID0gcmV0dXJuVmFsdWVzLnNsaWNlKDAsIHBvaW50Q291bnQpO1xuICAgICAgICAvLyBGaWxsIHdpdGggY291bnRcbiAgICAgICAgd2hpbGUgKHJldHVyblZhbHVlcy5sZW5ndGggPCBwb2ludENvdW50KSB7XG4gICAgICAgICAgdmFyIF9yZXR1cm5WYWx1ZXM7XG4gICAgICAgICAgcmV0dXJuVmFsdWVzLnB1c2goKF9yZXR1cm5WYWx1ZXMgPSByZXR1cm5WYWx1ZXNbcmV0dXJuVmFsdWVzLmxlbmd0aCAtIDFdKSAhPT0gbnVsbCAmJiBfcmV0dXJuVmFsdWVzICE9PSB2b2lkIDAgPyBfcmV0dXJuVmFsdWVzIDogbWVyZ2VkTWluKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuVmFsdWVzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGEgLSBiO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8vIEFsaWduIGluIHJhbmdlXG4gICAgcmV0dXJuVmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbCwgaW5kZXgpIHtcbiAgICAgIHJldHVyblZhbHVlc1tpbmRleF0gPSBmb3JtYXRWYWx1ZSh2YWwpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXR1cm5WYWx1ZXM7XG4gIH0sIFttZXJnZWRWYWx1ZSwgcmFuZ2UsIG1lcmdlZE1pbiwgY291bnQsIGZvcm1hdFZhbHVlXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBvbkNoYW5nZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHJhd1ZhbHVlc1JlZiA9IFJlYWN0LnVzZVJlZihyYXdWYWx1ZXMpO1xuICByYXdWYWx1ZXNSZWYuY3VycmVudCA9IHJhd1ZhbHVlcztcbiAgdmFyIGdldFRyaWdnZXJWYWx1ZSA9IGZ1bmN0aW9uIGdldFRyaWdnZXJWYWx1ZSh0cmlnZ2VyVmFsdWVzKSB7XG4gICAgcmV0dXJuIHJhbmdlID8gdHJpZ2dlclZhbHVlcyA6IHRyaWdnZXJWYWx1ZXNbMF07XG4gIH07XG4gIHZhciB0cmlnZ2VyQ2hhbmdlID0gZnVuY3Rpb24gdHJpZ2dlckNoYW5nZShuZXh0VmFsdWVzKSB7XG4gICAgLy8gT3JkZXIgZmlyc3RcbiAgICB2YXIgY2xvbmVOZXh0VmFsdWVzID0gX3RvQ29uc3VtYWJsZUFycmF5KG5leHRWYWx1ZXMpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgICAvLyBUcmlnZ2VyIGV2ZW50IGlmIG5lZWRlZFxuICAgIGlmIChvbkNoYW5nZSAmJiAhaXNFcXVhbChjbG9uZU5leHRWYWx1ZXMsIHJhd1ZhbHVlc1JlZi5jdXJyZW50LCB0cnVlKSkge1xuICAgICAgb25DaGFuZ2UoZ2V0VHJpZ2dlclZhbHVlKGNsb25lTmV4dFZhbHVlcykpO1xuICAgIH1cbiAgICAvLyBXZSBzZXQgdGhpcyBsYXRlciBzaW5jZSBpdCB3aWxsIHJlLXJlbmRlciBjb21wb25lbnQgaW1tZWRpYXRlbHlcbiAgICBzZXRWYWx1ZShjbG9uZU5leHRWYWx1ZXMpO1xuICB9O1xuICB2YXIgY2hhbmdlVG9DbG9zZVZhbHVlID0gZnVuY3Rpb24gY2hhbmdlVG9DbG9zZVZhbHVlKG5ld1ZhbHVlKSB7XG4gICAgaWYgKCFkaXNhYmxlZCkge1xuICAgICAgdmFyIHZhbHVlSW5kZXggPSAwO1xuICAgICAgdmFyIHZhbHVlRGlzdCA9IG1lcmdlZE1heCAtIG1lcmdlZE1pbjtcbiAgICAgIHJhd1ZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uICh2YWwsIGluZGV4KSB7XG4gICAgICAgIHZhciBkaXN0ID0gTWF0aC5hYnMobmV3VmFsdWUgLSB2YWwpO1xuICAgICAgICBpZiAoZGlzdCA8PSB2YWx1ZURpc3QpIHtcbiAgICAgICAgICB2YWx1ZURpc3QgPSBkaXN0O1xuICAgICAgICAgIHZhbHVlSW5kZXggPSBpbmRleDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBDcmVhdGUgbmV3IHZhbHVlc1xuICAgICAgdmFyIGNsb25lTmV4dFZhbHVlcyA9IF90b0NvbnN1bWFibGVBcnJheShyYXdWYWx1ZXMpO1xuICAgICAgY2xvbmVOZXh0VmFsdWVzW3ZhbHVlSW5kZXhdID0gbmV3VmFsdWU7XG4gICAgICAvLyBGaWxsIHZhbHVlIHRvIG1hdGNoIGRlZmF1bHQgMlxuICAgICAgaWYgKHJhbmdlICYmICFyYXdWYWx1ZXMubGVuZ3RoICYmIGNvdW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xvbmVOZXh0VmFsdWVzLnB1c2gobmV3VmFsdWUpO1xuICAgICAgfVxuICAgICAgb25CZWZvcmVDaGFuZ2UgPT09IG51bGwgfHwgb25CZWZvcmVDaGFuZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uQmVmb3JlQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShjbG9uZU5leHRWYWx1ZXMpKTtcbiAgICAgIHRyaWdnZXJDaGFuZ2UoY2xvbmVOZXh0VmFsdWVzKTtcbiAgICAgIG9uQWZ0ZXJDaGFuZ2UgPT09IG51bGwgfHwgb25BZnRlckNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25BZnRlckNoYW5nZShnZXRUcmlnZ2VyVmFsdWUoY2xvbmVOZXh0VmFsdWVzKSk7XG4gICAgfVxuICB9O1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09IENsaWNrID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBvblNsaWRlck1vdXNlRG93biA9IGZ1bmN0aW9uIG9uU2xpZGVyTW91c2VEb3duKGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdmFyIF9jb250YWluZXJSZWYkY3VycmVudCA9IGNvbnRhaW5lclJlZi5jdXJyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgd2lkdGggPSBfY29udGFpbmVyUmVmJGN1cnJlbnQud2lkdGgsXG4gICAgICBoZWlnaHQgPSBfY29udGFpbmVyUmVmJGN1cnJlbnQuaGVpZ2h0LFxuICAgICAgbGVmdCA9IF9jb250YWluZXJSZWYkY3VycmVudC5sZWZ0LFxuICAgICAgdG9wID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LnRvcCxcbiAgICAgIGJvdHRvbSA9IF9jb250YWluZXJSZWYkY3VycmVudC5ib3R0b20sXG4gICAgICByaWdodCA9IF9jb250YWluZXJSZWYkY3VycmVudC5yaWdodDtcbiAgICB2YXIgY2xpZW50WCA9IGUuY2xpZW50WCxcbiAgICAgIGNsaWVudFkgPSBlLmNsaWVudFk7XG4gICAgdmFyIHBlcmNlbnQ7XG4gICAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICAgIGNhc2UgJ2J0dCc6XG4gICAgICAgIHBlcmNlbnQgPSAoYm90dG9tIC0gY2xpZW50WSkgLyBoZWlnaHQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndHRiJzpcbiAgICAgICAgcGVyY2VudCA9IChjbGllbnRZIC0gdG9wKSAvIGhlaWdodDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdydGwnOlxuICAgICAgICBwZXJjZW50ID0gKHJpZ2h0IC0gY2xpZW50WCkgLyB3aWR0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBwZXJjZW50ID0gKGNsaWVudFggLSBsZWZ0KSAvIHdpZHRoO1xuICAgIH1cbiAgICB2YXIgbmV4dFZhbHVlID0gbWVyZ2VkTWluICsgcGVyY2VudCAqIChtZXJnZWRNYXggLSBtZXJnZWRNaW4pO1xuICAgIGNoYW5nZVRvQ2xvc2VWYWx1ZShmb3JtYXRWYWx1ZShuZXh0VmFsdWUpKTtcbiAgfTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IEtleWJvYXJkID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUobnVsbCksXG4gICAgX1JlYWN0JHVzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZSwgMiksXG4gICAga2V5Ym9hcmRWYWx1ZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgc2V0S2V5Ym9hcmRWYWx1ZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMV07XG4gIHZhciBvbkhhbmRsZU9mZnNldENoYW5nZSA9IGZ1bmN0aW9uIG9uSGFuZGxlT2Zmc2V0Q2hhbmdlKG9mZnNldCwgdmFsdWVJbmRleCkge1xuICAgIGlmICghZGlzYWJsZWQpIHtcbiAgICAgIHZhciBuZXh0ID0gb2Zmc2V0VmFsdWVzKHJhd1ZhbHVlcywgb2Zmc2V0LCB2YWx1ZUluZGV4KTtcbiAgICAgIG9uQmVmb3JlQ2hhbmdlID09PSBudWxsIHx8IG9uQmVmb3JlQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkJlZm9yZUNoYW5nZShnZXRUcmlnZ2VyVmFsdWUocmF3VmFsdWVzKSk7XG4gICAgICB0cmlnZ2VyQ2hhbmdlKG5leHQudmFsdWVzKTtcbiAgICAgIG9uQWZ0ZXJDaGFuZ2UgPT09IG51bGwgfHwgb25BZnRlckNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25BZnRlckNoYW5nZShnZXRUcmlnZ2VyVmFsdWUobmV4dC52YWx1ZXMpKTtcbiAgICAgIHNldEtleWJvYXJkVmFsdWUobmV4dC52YWx1ZSk7XG4gICAgfVxuICB9O1xuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChrZXlib2FyZFZhbHVlICE9PSBudWxsKSB7XG4gICAgICB2YXIgdmFsdWVJbmRleCA9IHJhd1ZhbHVlcy5pbmRleE9mKGtleWJvYXJkVmFsdWUpO1xuICAgICAgaWYgKHZhbHVlSW5kZXggPj0gMCkge1xuICAgICAgICBoYW5kbGVzUmVmLmN1cnJlbnQuZm9jdXModmFsdWVJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICAgIHNldEtleWJvYXJkVmFsdWUobnVsbCk7XG4gIH0sIFtrZXlib2FyZFZhbHVlXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09IERyYWcgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG1lcmdlZERyYWdnYWJsZVRyYWNrID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGRyYWdnYWJsZVRyYWNrICYmIG1lcmdlZFN0ZXAgPT09IG51bGwpIHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgIHdhcm5pbmcoZmFsc2UsICdgZHJhZ2dhYmxlVHJhY2tgIGlzIG5vdCBzdXBwb3J0ZWQgd2hlbiBgc3RlcGAgaXMgYG51bGxgLicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZHJhZ2dhYmxlVHJhY2s7XG4gIH0sIFtkcmFnZ2FibGVUcmFjaywgbWVyZ2VkU3RlcF0pO1xuICB2YXIgZmluaXNoQ2hhbmdlID0gZnVuY3Rpb24gZmluaXNoQ2hhbmdlKCkge1xuICAgIG9uQWZ0ZXJDaGFuZ2UgPT09IG51bGwgfHwgb25BZnRlckNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25BZnRlckNoYW5nZShnZXRUcmlnZ2VyVmFsdWUocmF3VmFsdWVzUmVmLmN1cnJlbnQpKTtcbiAgfTtcbiAgdmFyIF91c2VEcmFnID0gdXNlRHJhZyhjb250YWluZXJSZWYsIGRpcmVjdGlvbiwgcmF3VmFsdWVzLCBtZXJnZWRNaW4sIG1lcmdlZE1heCwgZm9ybWF0VmFsdWUsIHRyaWdnZXJDaGFuZ2UsIGZpbmlzaENoYW5nZSwgb2Zmc2V0VmFsdWVzKSxcbiAgICBfdXNlRHJhZzIgPSBfc2xpY2VkVG9BcnJheShfdXNlRHJhZywgNCksXG4gICAgZHJhZ2dpbmdJbmRleCA9IF91c2VEcmFnMlswXSxcbiAgICBkcmFnZ2luZ1ZhbHVlID0gX3VzZURyYWcyWzFdLFxuICAgIGNhY2hlVmFsdWVzID0gX3VzZURyYWcyWzJdLFxuICAgIG9uU3RhcnREcmFnID0gX3VzZURyYWcyWzNdO1xuICB2YXIgb25TdGFydE1vdmUgPSBmdW5jdGlvbiBvblN0YXJ0TW92ZShlLCB2YWx1ZUluZGV4KSB7XG4gICAgb25TdGFydERyYWcoZSwgdmFsdWVJbmRleCk7XG4gICAgb25CZWZvcmVDaGFuZ2UgPT09IG51bGwgfHwgb25CZWZvcmVDaGFuZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uQmVmb3JlQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShyYXdWYWx1ZXNSZWYuY3VycmVudCkpO1xuICB9O1xuICAvLyBBdXRvIGZvY3VzIGZvciB1cGRhdGVkIGhhbmRsZVxuICB2YXIgZHJhZ2dpbmcgPSBkcmFnZ2luZ0luZGV4ICE9PSAtMTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIWRyYWdnaW5nKSB7XG4gICAgICB2YXIgdmFsdWVJbmRleCA9IHJhd1ZhbHVlcy5sYXN0SW5kZXhPZihkcmFnZ2luZ1ZhbHVlKTtcbiAgICAgIGhhbmRsZXNSZWYuY3VycmVudC5mb2N1cyh2YWx1ZUluZGV4KTtcbiAgICB9XG4gIH0sIFtkcmFnZ2luZ10pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gSW5jbHVkZWQgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBzb3J0ZWRDYWNoZVZhbHVlcyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBfdG9Db25zdW1hYmxlQXJyYXkoY2FjaGVWYWx1ZXMpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIHJldHVybiBhIC0gYjtcbiAgICB9KTtcbiAgfSwgW2NhY2hlVmFsdWVzXSk7XG4gIC8vIFByb3ZpZGUgYSByYW5nZSB2YWx1ZXMgd2l0aCBpbmNsdWRlZCBbbWluLCBtYXhdXG4gIC8vIFVzZWQgZm9yIFRyYWNrLCBNYXJrICYgRG90XG4gIHZhciBfUmVhY3QkdXNlTWVtbyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKCFyYW5nZSkge1xuICAgICAgICByZXR1cm4gW21lcmdlZE1pbiwgc29ydGVkQ2FjaGVWYWx1ZXNbMF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtzb3J0ZWRDYWNoZVZhbHVlc1swXSwgc29ydGVkQ2FjaGVWYWx1ZXNbc29ydGVkQ2FjaGVWYWx1ZXMubGVuZ3RoIC0gMV1dO1xuICAgIH0sIFtzb3J0ZWRDYWNoZVZhbHVlcywgcmFuZ2UsIG1lcmdlZE1pbl0pLFxuICAgIF9SZWFjdCR1c2VNZW1vMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VNZW1vLCAyKSxcbiAgICBpbmNsdWRlZFN0YXJ0ID0gX1JlYWN0JHVzZU1lbW8yWzBdLFxuICAgIGluY2x1ZGVkRW5kID0gX1JlYWN0JHVzZU1lbW8yWzFdO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZWZzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIFJlYWN0LnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZvY3VzOiBmdW5jdGlvbiBmb2N1cygpIHtcbiAgICAgICAgaGFuZGxlc1JlZi5jdXJyZW50LmZvY3VzKDApO1xuICAgICAgfSxcbiAgICAgIGJsdXI6IGZ1bmN0aW9uIGJsdXIoKSB7XG4gICAgICAgIHZhciBfZG9jdW1lbnQgPSBkb2N1bWVudCxcbiAgICAgICAgICBhY3RpdmVFbGVtZW50ID0gX2RvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGlmIChjb250YWluZXJSZWYuY3VycmVudC5jb250YWlucyhhY3RpdmVFbGVtZW50KSkge1xuICAgICAgICAgIGFjdGl2ZUVsZW1lbnQgPT09IG51bGwgfHwgYWN0aXZlRWxlbWVudCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWN0aXZlRWxlbWVudC5ibHVyKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9KTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gQXV0byBGb2N1cyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChhdXRvRm9jdXMpIHtcbiAgICAgIGhhbmRsZXNSZWYuY3VycmVudC5mb2N1cygwKTtcbiAgICB9XG4gIH0sIFtdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IENvbnRleHQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgY29udGV4dCA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB7XG4gICAgICBtaW46IG1lcmdlZE1pbixcbiAgICAgIG1heDogbWVyZ2VkTWF4LFxuICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgICBkaXNhYmxlZDogZGlzYWJsZWQsXG4gICAgICBrZXlib2FyZDoga2V5Ym9hcmQsXG4gICAgICBzdGVwOiBtZXJnZWRTdGVwLFxuICAgICAgaW5jbHVkZWQ6IGluY2x1ZGVkLFxuICAgICAgaW5jbHVkZWRTdGFydDogaW5jbHVkZWRTdGFydCxcbiAgICAgIGluY2x1ZGVkRW5kOiBpbmNsdWRlZEVuZCxcbiAgICAgIHJhbmdlOiByYW5nZSxcbiAgICAgIHRhYkluZGV4OiB0YWJJbmRleCxcbiAgICAgIGFyaWFMYWJlbEZvckhhbmRsZTogYXJpYUxhYmVsRm9ySGFuZGxlLFxuICAgICAgYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGU6IGFyaWFMYWJlbGxlZEJ5Rm9ySGFuZGxlLFxuICAgICAgYXJpYVZhbHVlVGV4dEZvcm1hdHRlckZvckhhbmRsZTogYXJpYVZhbHVlVGV4dEZvcm1hdHRlckZvckhhbmRsZVxuICAgIH07XG4gIH0sIFttZXJnZWRNaW4sIG1lcmdlZE1heCwgZGlyZWN0aW9uLCBkaXNhYmxlZCwga2V5Ym9hcmQsIG1lcmdlZFN0ZXAsIGluY2x1ZGVkLCBpbmNsdWRlZFN0YXJ0LCBpbmNsdWRlZEVuZCwgcmFuZ2UsIHRhYkluZGV4LCBhcmlhTGFiZWxGb3JIYW5kbGUsIGFyaWFMYWJlbGxlZEJ5Rm9ySGFuZGxlLCBhcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFNsaWRlckNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogY29udGV4dFxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgcmVmOiBjb250YWluZXJSZWYsXG4gICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKHByZWZpeENscywgY2xhc3NOYW1lLCAoX2NsYXNzTmFtZXMgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9jbGFzc05hbWVzLCBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWRpc2FibGVkXCIpLCBkaXNhYmxlZCksIF9kZWZpbmVQcm9wZXJ0eShfY2xhc3NOYW1lcywgXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi12ZXJ0aWNhbFwiKSwgdmVydGljYWwpLCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIFwiXCIuY29uY2F0KHByZWZpeENscywgXCItaG9yaXpvbnRhbFwiKSwgIXZlcnRpY2FsKSwgX2RlZmluZVByb3BlcnR5KF9jbGFzc05hbWVzLCBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXdpdGgtbWFya3NcIiksIG1hcmtMaXN0Lmxlbmd0aCksIF9jbGFzc05hbWVzKSksXG4gICAgc3R5bGU6IHN0eWxlLFxuICAgIG9uTW91c2VEb3duOiBvblNsaWRlck1vdXNlRG93blxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXJhaWxcIiksXG4gICAgc3R5bGU6IHJhaWxTdHlsZVxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoVHJhY2tzLCB7XG4gICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgc3R5bGU6IHRyYWNrU3R5bGUsXG4gICAgdmFsdWVzOiBzb3J0ZWRDYWNoZVZhbHVlcyxcbiAgICBzdGFydFBvaW50OiBzdGFydFBvaW50LFxuICAgIG9uU3RhcnRNb3ZlOiBtZXJnZWREcmFnZ2FibGVUcmFjayA/IG9uU3RhcnRNb3ZlIDogbnVsbFxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoU3RlcHMsIHtcbiAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICBtYXJrczogbWFya0xpc3QsXG4gICAgZG90czogZG90cyxcbiAgICBzdHlsZTogZG90U3R5bGUsXG4gICAgYWN0aXZlU3R5bGU6IGFjdGl2ZURvdFN0eWxlXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChIYW5kbGVzLCB7XG4gICAgcmVmOiBoYW5kbGVzUmVmLFxuICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgIHN0eWxlOiBoYW5kbGVTdHlsZSxcbiAgICB2YWx1ZXM6IGNhY2hlVmFsdWVzLFxuICAgIGRyYWdnaW5nSW5kZXg6IGRyYWdnaW5nSW5kZXgsXG4gICAgb25TdGFydE1vdmU6IG9uU3RhcnRNb3ZlLFxuICAgIG9uT2Zmc2V0Q2hhbmdlOiBvbkhhbmRsZU9mZnNldENoYW5nZSxcbiAgICBvbkZvY3VzOiBvbkZvY3VzLFxuICAgIG9uQmx1cjogb25CbHVyLFxuICAgIGhhbmRsZVJlbmRlcjogaGFuZGxlUmVuZGVyXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNYXJrcywge1xuICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgIG1hcmtzOiBtYXJrTGlzdCxcbiAgICBvbkNsaWNrOiBjaGFuZ2VUb0Nsb3NlVmFsdWVcbiAgfSkpKTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgU2xpZGVyLmRpc3BsYXlOYW1lID0gJ1NsaWRlcic7XG59XG5leHBvcnQgZGVmYXVsdCBTbGlkZXI7IiwiaW1wb3J0IFNsaWRlciBmcm9tICcuL1NsaWRlcic7XG5leHBvcnQgZGVmYXVsdCBTbGlkZXI7IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbmplY3RTdHlsZXNJbnRvU3R5bGVUYWcuanNcIjtcbiAgICAgIGltcG9ydCBkb21BUEkgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlRG9tQVBJLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0Rm4gZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXMuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRTdHlsZUVsZW1lbnQgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydFN0eWxlRWxlbWVudC5qc1wiO1xuICAgICAgaW1wb3J0IHN0eWxlVGFnVHJhbnNmb3JtRm4gZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vYm9vdHN0cmFwLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xuXG4gICAgICBvcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xuICAgIFxub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9ib290c3RyYXAuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlTWVtbyhnZXRWYWx1ZSwgY29uZGl0aW9uLCBzaG91bGRVcGRhdGUpIHtcbiAgdmFyIGNhY2hlUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgaWYgKCEoJ3ZhbHVlJyBpbiBjYWNoZVJlZi5jdXJyZW50KSB8fCBzaG91bGRVcGRhdGUoY2FjaGVSZWYuY3VycmVudC5jb25kaXRpb24sIGNvbmRpdGlvbikpIHtcbiAgICBjYWNoZVJlZi5jdXJyZW50LnZhbHVlID0gZ2V0VmFsdWUoKTtcbiAgICBjYWNoZVJlZi5jdXJyZW50LmNvbmRpdGlvbiA9IGNvbmRpdGlvbjtcbiAgfVxuICByZXR1cm4gY2FjaGVSZWYuY3VycmVudC52YWx1ZTtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mXCI7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby1wYXJhbS1yZWFzc2lnbiAqL1xuXG5pbXBvcnQgeyBpc01lbW8gfSBmcm9tICdyZWFjdC1pcyc7XG5pbXBvcnQgdXNlTWVtbyBmcm9tIFwiLi9ob29rcy91c2VNZW1vXCI7XG5leHBvcnQgZnVuY3Rpb24gZmlsbFJlZihyZWYsIG5vZGUpIHtcbiAgaWYgKHR5cGVvZiByZWYgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZWYobm9kZSk7XG4gIH0gZWxzZSBpZiAoX3R5cGVvZihyZWYpID09PSAnb2JqZWN0JyAmJiByZWYgJiYgJ2N1cnJlbnQnIGluIHJlZikge1xuICAgIHJlZi5jdXJyZW50ID0gbm9kZTtcbiAgfVxufVxuXG4vKipcbiAqIE1lcmdlIHJlZnMgaW50byBvbmUgcmVmIGZ1bmN0aW9uIHRvIHN1cHBvcnQgcmVmIHBhc3NpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wb3NlUmVmKCkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgcmVmcyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICByZWZzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICB9XG4gIHZhciByZWZMaXN0ID0gcmVmcy5maWx0ZXIoZnVuY3Rpb24gKHJlZikge1xuICAgIHJldHVybiByZWY7XG4gIH0pO1xuICBpZiAocmVmTGlzdC5sZW5ndGggPD0gMSkge1xuICAgIHJldHVybiByZWZMaXN0WzBdO1xuICB9XG4gIHJldHVybiBmdW5jdGlvbiAobm9kZSkge1xuICAgIHJlZnMuZm9yRWFjaChmdW5jdGlvbiAocmVmKSB7XG4gICAgICBmaWxsUmVmKHJlZiwgbm9kZSk7XG4gICAgfSk7XG4gIH07XG59XG5leHBvcnQgZnVuY3Rpb24gdXNlQ29tcG9zZVJlZigpIHtcbiAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCByZWZzID0gbmV3IEFycmF5KF9sZW4yKSwgX2tleTIgPSAwOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgcmVmc1tfa2V5Ml0gPSBhcmd1bWVudHNbX2tleTJdO1xuICB9XG4gIHJldHVybiB1c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29tcG9zZVJlZi5hcHBseSh2b2lkIDAsIHJlZnMpO1xuICB9LCByZWZzLCBmdW5jdGlvbiAocHJldiwgbmV4dCkge1xuICAgIHJldHVybiBwcmV2Lmxlbmd0aCA9PT0gbmV4dC5sZW5ndGggJiYgcHJldi5ldmVyeShmdW5jdGlvbiAocmVmLCBpKSB7XG4gICAgICByZXR1cm4gcmVmID09PSBuZXh0W2ldO1xuICAgIH0pO1xuICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzdXBwb3J0UmVmKG5vZGVPckNvbXBvbmVudCkge1xuICB2YXIgX3R5cGUkcHJvdG90eXBlLCBfbm9kZU9yQ29tcG9uZW50JHByb3Q7XG4gIHZhciB0eXBlID0gaXNNZW1vKG5vZGVPckNvbXBvbmVudCkgPyBub2RlT3JDb21wb25lbnQudHlwZS50eXBlIDogbm9kZU9yQ29tcG9uZW50LnR5cGU7XG5cbiAgLy8gRnVuY3Rpb24gY29tcG9uZW50IG5vZGVcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nICYmICEoKF90eXBlJHByb3RvdHlwZSA9IHR5cGUucHJvdG90eXBlKSAhPT0gbnVsbCAmJiBfdHlwZSRwcm90b3R5cGUgIT09IHZvaWQgMCAmJiBfdHlwZSRwcm90b3R5cGUucmVuZGVyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIENsYXNzIGNvbXBvbmVudFxuICBpZiAodHlwZW9mIG5vZGVPckNvbXBvbmVudCA9PT0gJ2Z1bmN0aW9uJyAmJiAhKChfbm9kZU9yQ29tcG9uZW50JHByb3QgPSBub2RlT3JDb21wb25lbnQucHJvdG90eXBlKSAhPT0gbnVsbCAmJiBfbm9kZU9yQ29tcG9uZW50JHByb3QgIT09IHZvaWQgMCAmJiBfbm9kZU9yQ29tcG9uZW50JHByb3QucmVuZGVyKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbi8qIGVzbGludC1lbmFibGUgKi8iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG52YXIgT3JkZXJDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5leHBvcnQgZGVmYXVsdCBPcmRlckNvbnRleHQ7IiwiaW1wb3J0IF90b0NvbnN1bWFibGVBcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXlcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHVzZUxheW91dEVmZmVjdCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCBjYW5Vc2VEb20gZnJvbSBcInJjLXV0aWwvZXMvRG9tL2NhblVzZURvbVwiO1xuaW1wb3J0IE9yZGVyQ29udGV4dCBmcm9tIFwiLi9Db250ZXh0XCI7XG52YXIgRU1QVFlfTElTVCA9IFtdO1xuXG4vKipcbiAqIFdpbGwgYWRkIGBkaXZgIHRvIGRvY3VtZW50LiBOZXN0IGNhbGwgd2lsbCBrZWVwIG9yZGVyXG4gKiBAcGFyYW0gcmVuZGVyIFJlbmRlciBET00gaW4gZG9jdW1lbnRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlRG9tKHJlbmRlciwgZGVidWcpIHtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghY2FuVXNlRG9tKCkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICB2YXIgZGVmYXVsdEVsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgZGVidWcpIHtcbiAgICAgICAgZGVmYXVsdEVsZS5zZXRBdHRyaWJ1dGUoJ2RhdGEtZGVidWcnLCBkZWJ1Zyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGVmYXVsdEVsZTtcbiAgICB9KSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAxKSxcbiAgICBlbGUgPSBfUmVhY3QkdXNlU3RhdGUyWzBdO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IE9yZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBhcHBlbmRlZFJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIHZhciBxdWV1ZUNyZWF0ZSA9IFJlYWN0LnVzZUNvbnRleHQoT3JkZXJDb250ZXh0KTtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZTMgPSBSZWFjdC51c2VTdGF0ZShFTVBUWV9MSVNUKSxcbiAgICBfUmVhY3QkdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMywgMiksXG4gICAgcXVldWUgPSBfUmVhY3QkdXNlU3RhdGU0WzBdLFxuICAgIHNldFF1ZXVlID0gX1JlYWN0JHVzZVN0YXRlNFsxXTtcbiAgdmFyIG1lcmdlZFF1ZXVlQ3JlYXRlID0gcXVldWVDcmVhdGUgfHwgKGFwcGVuZGVkUmVmLmN1cnJlbnQgPyB1bmRlZmluZWQgOiBmdW5jdGlvbiAoYXBwZW5kRm4pIHtcbiAgICBzZXRRdWV1ZShmdW5jdGlvbiAob3JpZ2luKSB7XG4gICAgICB2YXIgbmV3UXVldWUgPSBbYXBwZW5kRm5dLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkob3JpZ2luKSk7XG4gICAgICByZXR1cm4gbmV3UXVldWU7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBET00gPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGZ1bmN0aW9uIGFwcGVuZCgpIHtcbiAgICBpZiAoIWVsZS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGVsZSk7XG4gICAgfVxuICAgIGFwcGVuZGVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuICB9XG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgdmFyIF9lbGUkcGFyZW50RWxlbWVudDtcbiAgICAoX2VsZSRwYXJlbnRFbGVtZW50ID0gZWxlLnBhcmVudEVsZW1lbnQpID09PSBudWxsIHx8IF9lbGUkcGFyZW50RWxlbWVudCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2VsZSRwYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKGVsZSk7XG4gICAgYXBwZW5kZWRSZWYuY3VycmVudCA9IGZhbHNlO1xuICB9XG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHJlbmRlcikge1xuICAgICAgaWYgKHF1ZXVlQ3JlYXRlKSB7XG4gICAgICAgIHF1ZXVlQ3JlYXRlKGFwcGVuZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcHBlbmQoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY2xlYW51cCgpO1xuICAgIH1cbiAgICByZXR1cm4gY2xlYW51cDtcbiAgfSwgW3JlbmRlcl0pO1xuICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgIHF1ZXVlLmZvckVhY2goZnVuY3Rpb24gKGFwcGVuZEZuKSB7XG4gICAgICAgIHJldHVybiBhcHBlbmRGbigpO1xuICAgICAgfSk7XG4gICAgICBzZXRRdWV1ZShFTVBUWV9MSVNUKTtcbiAgICB9XG4gIH0sIFtxdWV1ZV0pO1xuICByZXR1cm4gW2VsZSwgbWVyZ2VkUXVldWVDcmVhdGVdO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHJvb3QsIG4pIHtcbiAgaWYgKCFyb290KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVXNlIG5hdGl2ZSBpZiBzdXBwb3J0XG4gIGlmIChyb290LmNvbnRhaW5zKSB7XG4gICAgcmV0dXJuIHJvb3QuY29udGFpbnMobik7XG4gIH1cblxuICAvLyBgZG9jdW1lbnQuY29udGFpbnNgIG5vdCBzdXBwb3J0IHdpdGggSUUxMVxuICB2YXIgbm9kZSA9IG47XG4gIHdoaWxlIChub2RlKSB7XG4gICAgaWYgKG5vZGUgPT09IHJvb3QpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn0iLCJpbXBvcnQgY2FuVXNlRG9tIGZyb20gXCIuL2NhblVzZURvbVwiO1xuaW1wb3J0IGNvbnRhaW5zIGZyb20gXCIuL2NvbnRhaW5zXCI7XG52YXIgQVBQRU5EX09SREVSID0gJ2RhdGEtcmMtb3JkZXInO1xudmFyIE1BUktfS0VZID0gXCJyYy11dGlsLWtleVwiO1xudmFyIGNvbnRhaW5lckNhY2hlID0gbmV3IE1hcCgpO1xuZnVuY3Rpb24gZ2V0TWFyaygpIHtcbiAgdmFyIF9yZWYgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IHt9LFxuICAgIG1hcmsgPSBfcmVmLm1hcms7XG4gIGlmIChtYXJrKSB7XG4gICAgcmV0dXJuIG1hcmsuc3RhcnRzV2l0aCgnZGF0YS0nKSA/IG1hcmsgOiBcImRhdGEtXCIuY29uY2F0KG1hcmspO1xuICB9XG4gIHJldHVybiBNQVJLX0tFWTtcbn1cbmZ1bmN0aW9uIGdldENvbnRhaW5lcihvcHRpb24pIHtcbiAgaWYgKG9wdGlvbi5hdHRhY2hUbykge1xuICAgIHJldHVybiBvcHRpb24uYXR0YWNoVG87XG4gIH1cbiAgdmFyIGhlYWQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdoZWFkJyk7XG4gIHJldHVybiBoZWFkIHx8IGRvY3VtZW50LmJvZHk7XG59XG5mdW5jdGlvbiBnZXRPcmRlcihwcmVwZW5kKSB7XG4gIGlmIChwcmVwZW5kID09PSAncXVldWUnKSB7XG4gICAgcmV0dXJuICdwcmVwZW5kUXVldWUnO1xuICB9XG4gIHJldHVybiBwcmVwZW5kID8gJ3ByZXBlbmQnIDogJ2FwcGVuZCc7XG59XG5cbi8qKlxuICogRmluZCBzdHlsZSB3aGljaCBpbmplY3QgYnkgcmMtdXRpbFxuICovXG5mdW5jdGlvbiBmaW5kU3R5bGVzKGNvbnRhaW5lcikge1xuICByZXR1cm4gQXJyYXkuZnJvbSgoY29udGFpbmVyQ2FjaGUuZ2V0KGNvbnRhaW5lcikgfHwgY29udGFpbmVyKS5jaGlsZHJlbikuZmlsdGVyKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUudGFnTmFtZSA9PT0gJ1NUWUxFJztcbiAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0Q1NTKGNzcykge1xuICB2YXIgb3B0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgaWYgKCFjYW5Vc2VEb20oKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBjc3AgPSBvcHRpb24uY3NwLFxuICAgIHByZXBlbmQgPSBvcHRpb24ucHJlcGVuZDtcbiAgdmFyIHN0eWxlTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7XG4gIHN0eWxlTm9kZS5zZXRBdHRyaWJ1dGUoQVBQRU5EX09SREVSLCBnZXRPcmRlcihwcmVwZW5kKSk7XG4gIGlmIChjc3AgIT09IG51bGwgJiYgY3NwICE9PSB2b2lkIDAgJiYgY3NwLm5vbmNlKSB7XG4gICAgc3R5bGVOb2RlLm5vbmNlID0gY3NwID09PSBudWxsIHx8IGNzcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogY3NwLm5vbmNlO1xuICB9XG4gIHN0eWxlTm9kZS5pbm5lckhUTUwgPSBjc3M7XG4gIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIob3B0aW9uKTtcbiAgdmFyIGZpcnN0Q2hpbGQgPSBjb250YWluZXIuZmlyc3RDaGlsZDtcbiAgaWYgKHByZXBlbmQpIHtcbiAgICAvLyBJZiBpcyBxdWV1ZSBgcHJlcGVuZGAsIGl0IHdpbGwgcHJlcGVuZCBmaXJzdCBzdHlsZSBhbmQgdGhlbiBhcHBlbmQgcmVzdCBzdHlsZVxuICAgIGlmIChwcmVwZW5kID09PSAncXVldWUnKSB7XG4gICAgICB2YXIgZXhpc3RTdHlsZSA9IGZpbmRTdHlsZXMoY29udGFpbmVyKS5maWx0ZXIoZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIFsncHJlcGVuZCcsICdwcmVwZW5kUXVldWUnXS5pbmNsdWRlcyhub2RlLmdldEF0dHJpYnV0ZShBUFBFTkRfT1JERVIpKTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGV4aXN0U3R5bGUubGVuZ3RoKSB7XG4gICAgICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUoc3R5bGVOb2RlLCBleGlzdFN0eWxlW2V4aXN0U3R5bGUubGVuZ3RoIC0gMV0ubmV4dFNpYmxpbmcpO1xuICAgICAgICByZXR1cm4gc3R5bGVOb2RlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFVzZSBgaW5zZXJ0QmVmb3JlYCBhcyBgcHJlcGVuZGBcbiAgICBjb250YWluZXIuaW5zZXJ0QmVmb3JlKHN0eWxlTm9kZSwgZmlyc3RDaGlsZCk7XG4gIH0gZWxzZSB7XG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKHN0eWxlTm9kZSk7XG4gIH1cbiAgcmV0dXJuIHN0eWxlTm9kZTtcbn1cbmZ1bmN0aW9uIGZpbmRFeGlzdE5vZGUoa2V5KSB7XG4gIHZhciBvcHRpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICB2YXIgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyKG9wdGlvbik7XG4gIHJldHVybiBmaW5kU3R5bGVzKGNvbnRhaW5lcikuZmluZChmdW5jdGlvbiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZShnZXRNYXJrKG9wdGlvbikpID09PSBrZXk7XG4gIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUNTUyhrZXkpIHtcbiAgdmFyIG9wdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG4gIHZhciBleGlzdE5vZGUgPSBmaW5kRXhpc3ROb2RlKGtleSwgb3B0aW9uKTtcbiAgaWYgKGV4aXN0Tm9kZSkge1xuICAgIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIob3B0aW9uKTtcbiAgICBjb250YWluZXIucmVtb3ZlQ2hpbGQoZXhpc3ROb2RlKTtcbiAgfVxufVxuXG4vKipcbiAqIHFpYW5rdW4gd2lsbCBpbmplY3QgYGFwcGVuZENoaWxkYCB0byBpbnNlcnQgaW50byBvdGhlclxuICovXG5mdW5jdGlvbiBzeW5jUmVhbENvbnRhaW5lcihjb250YWluZXIsIG9wdGlvbikge1xuICB2YXIgY2FjaGVkUmVhbENvbnRhaW5lciA9IGNvbnRhaW5lckNhY2hlLmdldChjb250YWluZXIpO1xuXG4gIC8vIEZpbmQgcmVhbCBjb250YWluZXIgd2hlbiBub3QgY2FjaGVkIG9yIGNhY2hlZCBjb250YWluZXIgcmVtb3ZlZFxuICBpZiAoIWNhY2hlZFJlYWxDb250YWluZXIgfHwgIWNvbnRhaW5zKGRvY3VtZW50LCBjYWNoZWRSZWFsQ29udGFpbmVyKSkge1xuICAgIHZhciBwbGFjZWhvbGRlclN0eWxlID0gaW5qZWN0Q1NTKCcnLCBvcHRpb24pO1xuICAgIHZhciBwYXJlbnROb2RlID0gcGxhY2Vob2xkZXJTdHlsZS5wYXJlbnROb2RlO1xuICAgIGNvbnRhaW5lckNhY2hlLnNldChjb250YWluZXIsIHBhcmVudE5vZGUpO1xuICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChwbGFjZWhvbGRlclN0eWxlKTtcbiAgfVxufVxuXG4vKipcbiAqIG1hbnVhbGx5IGNsZWFyIGNvbnRhaW5lciBjYWNoZSB0byBhdm9pZCBnbG9iYWwgY2FjaGUgaW4gdW5pdCB0ZXN0ZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyQ29udGFpbmVyQ2FjaGUoKSB7XG4gIGNvbnRhaW5lckNhY2hlLmNsZWFyKCk7XG59XG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ1NTKGNzcywga2V5KSB7XG4gIHZhciBvcHRpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICB2YXIgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyKG9wdGlvbik7XG5cbiAgLy8gU3luYyByZWFsIHBhcmVudFxuICBzeW5jUmVhbENvbnRhaW5lcihjb250YWluZXIsIG9wdGlvbik7XG4gIHZhciBleGlzdE5vZGUgPSBmaW5kRXhpc3ROb2RlKGtleSwgb3B0aW9uKTtcbiAgaWYgKGV4aXN0Tm9kZSkge1xuICAgIHZhciBfb3B0aW9uJGNzcCwgX29wdGlvbiRjc3AyO1xuICAgIGlmICgoX29wdGlvbiRjc3AgPSBvcHRpb24uY3NwKSAhPT0gbnVsbCAmJiBfb3B0aW9uJGNzcCAhPT0gdm9pZCAwICYmIF9vcHRpb24kY3NwLm5vbmNlICYmIGV4aXN0Tm9kZS5ub25jZSAhPT0gKChfb3B0aW9uJGNzcDIgPSBvcHRpb24uY3NwKSA9PT0gbnVsbCB8fCBfb3B0aW9uJGNzcDIgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9vcHRpb24kY3NwMi5ub25jZSkpIHtcbiAgICAgIHZhciBfb3B0aW9uJGNzcDM7XG4gICAgICBleGlzdE5vZGUubm9uY2UgPSAoX29wdGlvbiRjc3AzID0gb3B0aW9uLmNzcCkgPT09IG51bGwgfHwgX29wdGlvbiRjc3AzID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfb3B0aW9uJGNzcDMubm9uY2U7XG4gICAgfVxuICAgIGlmIChleGlzdE5vZGUuaW5uZXJIVE1MICE9PSBjc3MpIHtcbiAgICAgIGV4aXN0Tm9kZS5pbm5lckhUTUwgPSBjc3M7XG4gICAgfVxuICAgIHJldHVybiBleGlzdE5vZGU7XG4gIH1cbiAgdmFyIG5ld05vZGUgPSBpbmplY3RDU1MoY3NzLCBvcHRpb24pO1xuICBuZXdOb2RlLnNldEF0dHJpYnV0ZShnZXRNYXJrKG9wdGlvbiksIGtleSk7XG4gIHJldHVybiBuZXdOb2RlO1xufSIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXBhcmFtLXJlYXNzaWduICovXG5cbnZhciBjYWNoZWQ7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRTY3JvbGxCYXJTaXplKGZyZXNoKSB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgaWYgKGZyZXNoIHx8IGNhY2hlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGlubmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgaW5uZXIuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgaW5uZXIuc3R5bGUuaGVpZ2h0ID0gJzIwMHB4JztcbiAgICB2YXIgb3V0ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB2YXIgb3V0ZXJTdHlsZSA9IG91dGVyLnN0eWxlO1xuICAgIG91dGVyU3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIG91dGVyU3R5bGUudG9wID0gJzAnO1xuICAgIG91dGVyU3R5bGUubGVmdCA9ICcwJztcbiAgICBvdXRlclN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gICAgb3V0ZXJTdHlsZS52aXNpYmlsaXR5ID0gJ2hpZGRlbic7XG4gICAgb3V0ZXJTdHlsZS53aWR0aCA9ICcyMDBweCc7XG4gICAgb3V0ZXJTdHlsZS5oZWlnaHQgPSAnMTUwcHgnO1xuICAgIG91dGVyU3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgICBvdXRlci5hcHBlbmRDaGlsZChpbm5lcik7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChvdXRlcik7XG4gICAgdmFyIHdpZHRoQ29udGFpbmVkID0gaW5uZXIub2Zmc2V0V2lkdGg7XG4gICAgb3V0ZXIuc3R5bGUub3ZlcmZsb3cgPSAnc2Nyb2xsJztcbiAgICB2YXIgd2lkdGhTY3JvbGwgPSBpbm5lci5vZmZzZXRXaWR0aDtcbiAgICBpZiAod2lkdGhDb250YWluZWQgPT09IHdpZHRoU2Nyb2xsKSB7XG4gICAgICB3aWR0aFNjcm9sbCA9IG91dGVyLmNsaWVudFdpZHRoO1xuICAgIH1cbiAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKG91dGVyKTtcbiAgICBjYWNoZWQgPSB3aWR0aENvbnRhaW5lZCAtIHdpZHRoU2Nyb2xsO1xuICB9XG4gIHJldHVybiBjYWNoZWQ7XG59XG5mdW5jdGlvbiBlbnN1cmVTaXplKHN0cikge1xuICB2YXIgbWF0Y2ggPSBzdHIubWF0Y2goL14oLiopcHgkLyk7XG4gIHZhciB2YWx1ZSA9IE51bWJlcihtYXRjaCA9PT0gbnVsbCB8fCBtYXRjaCA9PT0gdm9pZCAwID8gdm9pZCAwIDogbWF0Y2hbMV0pO1xuICByZXR1cm4gTnVtYmVyLmlzTmFOKHZhbHVlKSA/IGdldFNjcm9sbEJhclNpemUoKSA6IHZhbHVlO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFRhcmdldFNjcm9sbEJhclNpemUodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICF0YXJnZXQgfHwgISh0YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50KSkge1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogMCxcbiAgICAgIGhlaWdodDogMFxuICAgIH07XG4gIH1cbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQsICc6Oi13ZWJraXQtc2Nyb2xsYmFyJyksXG4gICAgd2lkdGggPSBfZ2V0Q29tcHV0ZWRTdHlsZS53aWR0aCxcbiAgICBoZWlnaHQgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5oZWlnaHQ7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IGVuc3VyZVNpemUod2lkdGgpLFxuICAgIGhlaWdodDogZW5zdXJlU2l6ZShoZWlnaHQpXG4gIH07XG59IiwiLyoqXG4gKiBUZXN0IHVzYWdlIGV4cG9ydC4gRG8gbm90IHVzZSBpbiB5b3VyIHByb2R1Y3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9keU92ZXJmbG93aW5nKCkge1xuICByZXR1cm4gZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQgPiAod2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpICYmIHdpbmRvdy5pbm5lcldpZHRoID4gZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aDtcbn0iLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVwZGF0ZUNTUywgcmVtb3ZlQ1NTIH0gZnJvbSBcInJjLXV0aWwvZXMvRG9tL2R5bmFtaWNDU1NcIjtcbmltcG9ydCB1c2VMYXlvdXRFZmZlY3QgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlTGF5b3V0RWZmZWN0XCI7XG5pbXBvcnQgZ2V0U2Nyb2xsQmFyU2l6ZSBmcm9tIFwicmMtdXRpbC9lcy9nZXRTY3JvbGxCYXJTaXplXCI7XG5pbXBvcnQgeyBpc0JvZHlPdmVyZmxvd2luZyB9IGZyb20gXCIuL3V0aWxcIjtcbnZhciBVTklRVUVfSUQgPSBcInJjLXV0aWwtbG9ja2VyLVwiLmNvbmNhdChEYXRlLm5vdygpKTtcbnZhciB1dWlkID0gMDtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZVNjcm9sbExvY2tlcihsb2NrKSB7XG4gIHZhciBtZXJnZWRMb2NrID0gISFsb2NrO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgdXVpZCArPSAxO1xuICAgICAgcmV0dXJuIFwiXCIuY29uY2F0KFVOSVFVRV9JRCwgXCJfXCIpLmNvbmNhdCh1dWlkKTtcbiAgICB9KSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAxKSxcbiAgICBpZCA9IF9SZWFjdCR1c2VTdGF0ZTJbMF07XG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG1lcmdlZExvY2spIHtcbiAgICAgIHZhciBzY3JvbGxiYXJTaXplID0gZ2V0U2Nyb2xsQmFyU2l6ZSgpO1xuICAgICAgdmFyIGlzT3ZlcmZsb3cgPSBpc0JvZHlPdmVyZmxvd2luZygpO1xuICAgICAgdXBkYXRlQ1NTKFwiXFxuaHRtbCBib2R5IHtcXG4gIG92ZXJmbG93LXk6IGhpZGRlbjtcXG4gIFwiLmNvbmNhdChpc092ZXJmbG93ID8gXCJ3aWR0aDogY2FsYygxMDAlIC0gXCIuY29uY2F0KHNjcm9sbGJhclNpemUsIFwicHgpO1wiKSA6ICcnLCBcIlxcbn1cIiksIGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVtb3ZlQ1NTKGlkKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlbW92ZUNTUyhpZCk7XG4gICAgfTtcbiAgfSwgW21lcmdlZExvY2ssIGlkXSk7XG59IiwiZXhwb3J0IHZhciBpbmxpbmUgPSBmYWxzZTtcbmV4cG9ydCBmdW5jdGlvbiBpbmxpbmVNb2NrKG5leHRJbmxpbmUpIHtcbiAgaWYgKHR5cGVvZiBuZXh0SW5saW5lID09PSAnYm9vbGVhbicpIHtcbiAgICBpbmxpbmUgPSBuZXh0SW5saW5lO1xuICB9XG4gIHJldHVybiBpbmxpbmU7XG59IiwiaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBjcmVhdGVQb3J0YWwgfSBmcm9tICdyZWFjdC1kb20nO1xuaW1wb3J0IGNhblVzZURvbSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vY2FuVXNlRG9tXCI7XG5pbXBvcnQgd2FybmluZyBmcm9tIFwicmMtdXRpbC9lcy93YXJuaW5nXCI7XG5pbXBvcnQgeyBzdXBwb3J0UmVmLCB1c2VDb21wb3NlUmVmIH0gZnJvbSBcInJjLXV0aWwvZXMvcmVmXCI7XG5pbXBvcnQgT3JkZXJDb250ZXh0IGZyb20gXCIuL0NvbnRleHRcIjtcbmltcG9ydCB1c2VEb20gZnJvbSBcIi4vdXNlRG9tXCI7XG5pbXBvcnQgdXNlU2Nyb2xsTG9ja2VyIGZyb20gXCIuL3VzZVNjcm9sbExvY2tlclwiO1xuaW1wb3J0IHsgaW5saW5lTW9jayB9IGZyb20gXCIuL21vY2tcIjtcbnZhciBnZXRQb3J0YWxDb250YWluZXIgPSBmdW5jdGlvbiBnZXRQb3J0YWxDb250YWluZXIoZ2V0Q29udGFpbmVyKSB7XG4gIGlmIChnZXRDb250YWluZXIgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICghY2FuVXNlRG9tKCkgfHwgIWdldENvbnRhaW5lcikge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmICh0eXBlb2YgZ2V0Q29udGFpbmVyID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGdldENvbnRhaW5lcik7XG4gIH1cbiAgaWYgKHR5cGVvZiBnZXRDb250YWluZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZ2V0Q29udGFpbmVyKCk7XG4gIH1cbiAgcmV0dXJuIGdldENvbnRhaW5lcjtcbn07XG52YXIgUG9ydGFsID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgdmFyIG9wZW4gPSBwcm9wcy5vcGVuLFxuICAgIGF1dG9Mb2NrID0gcHJvcHMuYXV0b0xvY2ssXG4gICAgZ2V0Q29udGFpbmVyID0gcHJvcHMuZ2V0Q29udGFpbmVyLFxuICAgIGRlYnVnID0gcHJvcHMuZGVidWcsXG4gICAgX3Byb3BzJGF1dG9EZXN0cm95ID0gcHJvcHMuYXV0b0Rlc3Ryb3ksXG4gICAgYXV0b0Rlc3Ryb3kgPSBfcHJvcHMkYXV0b0Rlc3Ryb3kgPT09IHZvaWQgMCA/IHRydWUgOiBfcHJvcHMkYXV0b0Rlc3Ryb3ksXG4gICAgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbjtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKG9wZW4pLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDIpLFxuICAgIHNob3VsZFJlbmRlciA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgc2V0U2hvdWxkUmVuZGVyID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgdmFyIG1lcmdlZFJlbmRlciA9IHNob3VsZFJlbmRlciB8fCBvcGVuO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT0gV2FybmluZyA9PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgd2FybmluZyhjYW5Vc2VEb20oKSB8fCAhb3BlbiwgXCJQb3J0YWwgb25seSB3b3JrIGluIGNsaWVudCBzaWRlLiBQbGVhc2UgY2FsbCAndXNlRWZmZWN0JyB0byBzaG93IFBvcnRhbCBpbnN0ZWFkIGRlZmF1bHQgcmVuZGVyIGluIFNTUi5cIik7XG4gIH1cblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09IFNob3VsZCBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PVxuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChhdXRvRGVzdHJveSB8fCBvcGVuKSB7XG4gICAgICBzZXRTaG91bGRSZW5kZXIob3Blbik7XG4gICAgfVxuICB9LCBbb3BlbiwgYXV0b0Rlc3Ryb3ldKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT0gQ29udGFpbmVyID09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgX1JlYWN0JHVzZVN0YXRlMyA9IFJlYWN0LnVzZVN0YXRlKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXRQb3J0YWxDb250YWluZXIoZ2V0Q29udGFpbmVyKTtcbiAgICB9KSxcbiAgICBfUmVhY3QkdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMywgMiksXG4gICAgaW5uZXJDb250YWluZXIgPSBfUmVhY3QkdXNlU3RhdGU0WzBdLFxuICAgIHNldElubmVyQ29udGFpbmVyID0gX1JlYWN0JHVzZVN0YXRlNFsxXTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY3VzdG9taXplQ29udGFpbmVyID0gZ2V0UG9ydGFsQ29udGFpbmVyKGdldENvbnRhaW5lcik7XG5cbiAgICAvLyBUZWxsIGNvbXBvbmVudCB0aGF0IHdlIGNoZWNrIHRoaXMgaW4gZWZmZWN0IHdoaWNoIGlzIHNhZmUgdG8gYmUgYG51bGxgXG4gICAgc2V0SW5uZXJDb250YWluZXIoY3VzdG9taXplQ29udGFpbmVyICE9PSBudWxsICYmIGN1c3RvbWl6ZUNvbnRhaW5lciAhPT0gdm9pZCAwID8gY3VzdG9taXplQ29udGFpbmVyIDogbnVsbCk7XG4gIH0pO1xuICB2YXIgX3VzZURvbSA9IHVzZURvbShtZXJnZWRSZW5kZXIgJiYgIWlubmVyQ29udGFpbmVyLCBkZWJ1ZyksXG4gICAgX3VzZURvbTIgPSBfc2xpY2VkVG9BcnJheShfdXNlRG9tLCAyKSxcbiAgICBkZWZhdWx0Q29udGFpbmVyID0gX3VzZURvbTJbMF0sXG4gICAgcXVldWVDcmVhdGUgPSBfdXNlRG9tMlsxXTtcbiAgdmFyIG1lcmdlZENvbnRhaW5lciA9IGlubmVyQ29udGFpbmVyICE9PSBudWxsICYmIGlubmVyQ29udGFpbmVyICE9PSB2b2lkIDAgPyBpbm5lckNvbnRhaW5lciA6IGRlZmF1bHRDb250YWluZXI7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBMb2NrZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdXNlU2Nyb2xsTG9ja2VyKGF1dG9Mb2NrICYmIG9wZW4gJiYgY2FuVXNlRG9tKCkgJiYgKG1lcmdlZENvbnRhaW5lciA9PT0gZGVmYXVsdENvbnRhaW5lciB8fCBtZXJnZWRDb250YWluZXIgPT09IGRvY3VtZW50LmJvZHkpKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVmID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgY2hpbGRSZWYgPSBudWxsO1xuICBpZiAoY2hpbGRyZW4gJiYgc3VwcG9ydFJlZihjaGlsZHJlbikgJiYgcmVmKSB7XG4gICAgdmFyIF9yZWYgPSBjaGlsZHJlbjtcbiAgICBjaGlsZFJlZiA9IF9yZWYucmVmO1xuICB9XG4gIHZhciBtZXJnZWRSZWYgPSB1c2VDb21wb3NlUmVmKGNoaWxkUmVmLCByZWYpO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIERvIG5vdCByZW5kZXIgd2hlbiBub3RoaW5nIG5lZWQgcmVuZGVyXG4gIC8vIFdoZW4gaW5uZXJDb250YWluZXIgaXMgYHVuZGVmaW5lZGAsIGl0IG1heSBub3QgcmVhZHkgc2luY2UgdXNlciB1c2UgcmVmIGluIHRoZSBzYW1lIHJlbmRlclxuICBpZiAoIW1lcmdlZFJlbmRlciB8fCAhY2FuVXNlRG9tKCkgfHwgaW5uZXJDb250YWluZXIgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gUmVuZGVyIGlubGluZVxuICB2YXIgcmVuZGVySW5saW5lID0gbWVyZ2VkQ29udGFpbmVyID09PSBmYWxzZSB8fCBpbmxpbmVNb2NrKCk7XG4gIHZhciByZWZmZWRDaGlsZHJlbiA9IGNoaWxkcmVuO1xuICBpZiAocmVmKSB7XG4gICAgcmVmZmVkQ2hpbGRyZW4gPSAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KGNoaWxkcmVuLCB7XG4gICAgICByZWY6IG1lcmdlZFJlZlxuICAgIH0pO1xuICB9XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChPcmRlckNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogcXVldWVDcmVhdGVcbiAgfSwgcmVuZGVySW5saW5lID8gcmVmZmVkQ2hpbGRyZW4gOiAvKiNfX1BVUkVfXyovY3JlYXRlUG9ydGFsKHJlZmZlZENoaWxkcmVuLCBtZXJnZWRDb250YWluZXIpKTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgUG9ydGFsLmRpc3BsYXlOYW1lID0gJ1BvcnRhbCc7XG59XG5leHBvcnQgZGVmYXVsdCBQb3J0YWw7IiwiaW1wb3J0IFBvcnRhbCBmcm9tIFwiLi9Qb3J0YWxcIjtcbmltcG9ydCB7IGlubGluZU1vY2sgfSBmcm9tIFwiLi9tb2NrXCI7XG5leHBvcnQgeyBpbmxpbmVNb2NrIH07XG5leHBvcnQgZGVmYXVsdCBQb3J0YWw7IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGlzRnJhZ21lbnQgfSBmcm9tICdyZWFjdC1pcyc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0b0FycmF5KGNoaWxkcmVuKSB7XG4gIHZhciBvcHRpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICB2YXIgcmV0ID0gW107XG4gIFJlYWN0LkNoaWxkcmVuLmZvckVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uIChjaGlsZCkge1xuICAgIGlmICgoY2hpbGQgPT09IHVuZGVmaW5lZCB8fCBjaGlsZCA9PT0gbnVsbCkgJiYgIW9wdGlvbi5rZWVwRW1wdHkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSB7XG4gICAgICByZXQgPSByZXQuY29uY2F0KHRvQXJyYXkoY2hpbGQpKTtcbiAgICB9IGVsc2UgaWYgKGlzRnJhZ21lbnQoY2hpbGQpICYmIGNoaWxkLnByb3BzKSB7XG4gICAgICByZXQgPSByZXQuY29uY2F0KHRvQXJyYXkoY2hpbGQucHJvcHMuY2hpbGRyZW4sIG9wdGlvbikpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXQucHVzaChjaGlsZCk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJldDtcbn0iLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFJlYWN0RE9NIGZyb20gJ3JlYWN0LWRvbSc7XG5leHBvcnQgZnVuY3Rpb24gaXNET00obm9kZSkge1xuICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudFxuICAvLyBTaW5jZSBYVUxFbGVtZW50IGlzIGFsc28gc3ViY2xhc3Mgb2YgRWxlbWVudCwgd2Ugb25seSBuZWVkIEhUTUxFbGVtZW50IGFuZCBTVkdFbGVtZW50XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIFNWR0VsZW1lbnQ7XG59XG5cbi8qKlxuICogUmV0dXJuIGlmIGEgbm9kZSBpcyBhIERPTSBub2RlLiBFbHNlIHdpbGwgcmV0dXJuIGJ5IGBmaW5kRE9NTm9kZWBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZmluZERPTU5vZGUobm9kZSkge1xuICBpZiAoaXNET00obm9kZSkpIHtcbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuICBpZiAobm9kZSBpbnN0YW5jZW9mIFJlYWN0LkNvbXBvbmVudCkge1xuICAgIHJldHVybiBSZWFjdERPTS5maW5kRE9NTm9kZShub2RlKTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn0iLCIvKipcclxuICogQSBjb2xsZWN0aW9uIG9mIHNoaW1zIHRoYXQgcHJvdmlkZSBtaW5pbWFsIGZ1bmN0aW9uYWxpdHkgb2YgdGhlIEVTNiBjb2xsZWN0aW9ucy5cclxuICpcclxuICogVGhlc2UgaW1wbGVtZW50YXRpb25zIGFyZSBub3QgbWVhbnQgdG8gYmUgdXNlZCBvdXRzaWRlIG9mIHRoZSBSZXNpemVPYnNlcnZlclxyXG4gKiBtb2R1bGVzIGFzIHRoZXkgY292ZXIgb25seSBhIGxpbWl0ZWQgcmFuZ2Ugb2YgdXNlIGNhc2VzLlxyXG4gKi9cclxuLyogZXNsaW50LWRpc2FibGUgcmVxdWlyZS1qc2RvYywgdmFsaWQtanNkb2MgKi9cclxudmFyIE1hcFNoaW0gPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgaWYgKHR5cGVvZiBNYXAgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgcmV0dXJuIE1hcDtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBpbmRleCBpbiBwcm92aWRlZCBhcnJheSB0aGF0IG1hdGNoZXMgdGhlIHNwZWNpZmllZCBrZXkuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtBcnJheTxBcnJheT59IGFyclxyXG4gICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldEluZGV4KGFyciwga2V5KSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IC0xO1xyXG4gICAgICAgIGFyci5zb21lKGZ1bmN0aW9uIChlbnRyeSwgaW5kZXgpIHtcclxuICAgICAgICAgICAgaWYgKGVudHJ5WzBdID09PSBrZXkpIHtcclxuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGluZGV4O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGNsYXNzXzEoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX19lbnRyaWVzX18gPSBbXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsYXNzXzEucHJvdG90eXBlLCBcInNpemVcIiwge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9fZW50cmllc19fLmxlbmd0aDtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAgICAgKiBAcmV0dXJucyB7Kn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGdldEluZGV4KHRoaXMuX19lbnRyaWVzX18sIGtleSk7XHJcbiAgICAgICAgICAgIHZhciBlbnRyeSA9IHRoaXMuX19lbnRyaWVzX19baW5kZXhdO1xyXG4gICAgICAgICAgICByZXR1cm4gZW50cnkgJiYgZW50cnlbMV07XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICAgICAqIEBwYXJhbSB7Kn0gdmFsdWVcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgICAgICB2YXIgaW5kZXggPSBnZXRJbmRleCh0aGlzLl9fZW50cmllc19fLCBrZXkpO1xyXG4gICAgICAgICAgICBpZiAofmluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9fZW50cmllc19fW2luZGV4XVsxXSA9IHZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fX2VudHJpZXNfXy5wdXNoKFtrZXksIHZhbHVlXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwYXJhbSB7Kn0ga2V5XHJcbiAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY2xhc3NfMS5wcm90b3R5cGUuZGVsZXRlID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgICAgICB2YXIgZW50cmllcyA9IHRoaXMuX19lbnRyaWVzX187XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGdldEluZGV4KGVudHJpZXMsIGtleSk7XHJcbiAgICAgICAgICAgIGlmICh+aW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIGVudHJpZXMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiAhIX5nZXRJbmRleCh0aGlzLl9fZW50cmllc19fLCBrZXkpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgY2xhc3NfMS5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX19lbnRyaWVzX18uc3BsaWNlKDApO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcclxuICAgICAgICAgKiBAcGFyYW0geyp9IFtjdHg9bnVsbF1cclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrLCBjdHgpIHtcclxuICAgICAgICAgICAgaWYgKGN0eCA9PT0gdm9pZCAwKSB7IGN0eCA9IG51bGw7IH1cclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuX19lbnRyaWVzX187IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZW50cnkgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKGN0eCwgZW50cnlbMV0sIGVudHJ5WzBdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIGNsYXNzXzE7XHJcbiAgICB9KCkpO1xyXG59KSgpO1xuXG4vKipcclxuICogRGV0ZWN0cyB3aGV0aGVyIHdpbmRvdyBhbmQgZG9jdW1lbnQgb2JqZWN0cyBhcmUgYXZhaWxhYmxlIGluIGN1cnJlbnQgZW52aXJvbm1lbnQuXHJcbiAqL1xyXG52YXIgaXNCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuZG9jdW1lbnQgPT09IGRvY3VtZW50O1xuXG4vLyBSZXR1cm5zIGdsb2JhbCBvYmplY3Qgb2YgYSBjdXJyZW50IGVudmlyb25tZW50LlxyXG52YXIgZ2xvYmFsJDEgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbC5NYXRoID09PSBNYXRoKSB7XHJcbiAgICAgICAgcmV0dXJuIGdsb2JhbDtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09PSBNYXRoKSB7XHJcbiAgICAgICAgcmV0dXJuIHNlbGY7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93Lk1hdGggPT09IE1hdGgpIHtcclxuICAgICAgICByZXR1cm4gd2luZG93O1xyXG4gICAgfVxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXHJcbiAgICByZXR1cm4gRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcclxufSkoKTtcblxuLyoqXHJcbiAqIEEgc2hpbSBmb3IgdGhlIHJlcXVlc3RBbmltYXRpb25GcmFtZSB3aGljaCBmYWxscyBiYWNrIHRvIHRoZSBzZXRUaW1lb3V0IGlmXHJcbiAqIGZpcnN0IG9uZSBpcyBub3Qgc3VwcG9ydGVkLlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXF1ZXN0cycgaWRlbnRpZmllci5cclxuICovXHJcbnZhciByZXF1ZXN0QW5pbWF0aW9uRnJhbWUkMSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIC8vIEl0J3MgcmVxdWlyZWQgdG8gdXNlIGEgYm91bmRlZCBmdW5jdGlvbiBiZWNhdXNlIElFIHNvbWV0aW1lcyB0aHJvd3NcclxuICAgICAgICAvLyBhbiBcIkludmFsaWQgY2FsbGluZyBvYmplY3RcIiBlcnJvciBpZiByQUYgaXMgaW52b2tlZCB3aXRob3V0IHRoZSBnbG9iYWxcclxuICAgICAgICAvLyBvYmplY3Qgb24gdGhlIGxlZnQgaGFuZCBzaWRlLlxyXG4gICAgICAgIHJldHVybiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUuYmluZChnbG9iYWwkMSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGNhbGxiYWNrKSB7IHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIGNhbGxiYWNrKERhdGUubm93KCkpOyB9LCAxMDAwIC8gNjApOyB9O1xyXG59KSgpO1xuXG4vLyBEZWZpbmVzIG1pbmltdW0gdGltZW91dCBiZWZvcmUgYWRkaW5nIGEgdHJhaWxpbmcgY2FsbC5cclxudmFyIHRyYWlsaW5nVGltZW91dCA9IDI7XHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgd3JhcHBlciBmdW5jdGlvbiB3aGljaCBlbnN1cmVzIHRoYXQgcHJvdmlkZWQgY2FsbGJhY2sgd2lsbCBiZVxyXG4gKiBpbnZva2VkIG9ubHkgb25jZSBkdXJpbmcgdGhlIHNwZWNpZmllZCBkZWxheSBwZXJpb2QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gYmUgaW52b2tlZCBhZnRlciB0aGUgZGVsYXkgcGVyaW9kLlxyXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsYXkgLSBEZWxheSBhZnRlciB3aGljaCB0byBpbnZva2UgY2FsbGJhY2suXHJcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn1cclxuICovXHJcbmZ1bmN0aW9uIHRocm90dGxlIChjYWxsYmFjaywgZGVsYXkpIHtcclxuICAgIHZhciBsZWFkaW5nQ2FsbCA9IGZhbHNlLCB0cmFpbGluZ0NhbGwgPSBmYWxzZSwgbGFzdENhbGxUaW1lID0gMDtcclxuICAgIC8qKlxyXG4gICAgICogSW52b2tlcyB0aGUgb3JpZ2luYWwgY2FsbGJhY2sgZnVuY3Rpb24gYW5kIHNjaGVkdWxlcyBuZXcgaW52b2NhdGlvbiBpZlxyXG4gICAgICogdGhlIFwicHJveHlcIiB3YXMgY2FsbGVkIGR1cmluZyBjdXJyZW50IHJlcXVlc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHJlc29sdmVQZW5kaW5nKCkge1xyXG4gICAgICAgIGlmIChsZWFkaW5nQ2FsbCkge1xyXG4gICAgICAgICAgICBsZWFkaW5nQ2FsbCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBjYWxsYmFjaygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHJhaWxpbmdDYWxsKSB7XHJcbiAgICAgICAgICAgIHByb3h5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayBpbnZva2VkIGFmdGVyIHRoZSBzcGVjaWZpZWQgZGVsYXkuIEl0IHdpbGwgZnVydGhlciBwb3N0cG9uZVxyXG4gICAgICogaW52b2NhdGlvbiBvZiB0aGUgb3JpZ2luYWwgZnVuY3Rpb24gZGVsZWdhdGluZyBpdCB0byB0aGVcclxuICAgICAqIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gdGltZW91dENhbGxiYWNrKCkge1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSQxKHJlc29sdmVQZW5kaW5nKTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU2NoZWR1bGVzIGludm9jYXRpb24gb2YgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBwcm94eSgpIHtcclxuICAgICAgICB2YXIgdGltZVN0YW1wID0gRGF0ZS5ub3coKTtcclxuICAgICAgICBpZiAobGVhZGluZ0NhbGwpIHtcclxuICAgICAgICAgICAgLy8gUmVqZWN0IGltbWVkaWF0ZWx5IGZvbGxvd2luZyBjYWxscy5cclxuICAgICAgICAgICAgaWYgKHRpbWVTdGFtcCAtIGxhc3RDYWxsVGltZSA8IHRyYWlsaW5nVGltZW91dCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFNjaGVkdWxlIG5ldyBjYWxsIHRvIGJlIGluIGludm9rZWQgd2hlbiB0aGUgcGVuZGluZyBvbmUgaXMgcmVzb2x2ZWQuXHJcbiAgICAgICAgICAgIC8vIFRoaXMgaXMgaW1wb3J0YW50IGZvciBcInRyYW5zaXRpb25zXCIgd2hpY2ggbmV2ZXIgYWN0dWFsbHkgc3RhcnRcclxuICAgICAgICAgICAgLy8gaW1tZWRpYXRlbHkgc28gdGhlcmUgaXMgYSBjaGFuY2UgdGhhdCB3ZSBtaWdodCBtaXNzIG9uZSBpZiBjaGFuZ2VcclxuICAgICAgICAgICAgLy8gaGFwcGVucyBhbWlkcyB0aGUgcGVuZGluZyBpbnZvY2F0aW9uLlxyXG4gICAgICAgICAgICB0cmFpbGluZ0NhbGwgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgbGVhZGluZ0NhbGwgPSB0cnVlO1xyXG4gICAgICAgICAgICB0cmFpbGluZ0NhbGwgPSBmYWxzZTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCh0aW1lb3V0Q2FsbGJhY2ssIGRlbGF5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgbGFzdENhbGxUaW1lID0gdGltZVN0YW1wO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHByb3h5O1xyXG59XG5cbi8vIE1pbmltdW0gZGVsYXkgYmVmb3JlIGludm9raW5nIHRoZSB1cGRhdGUgb2Ygb2JzZXJ2ZXJzLlxyXG52YXIgUkVGUkVTSF9ERUxBWSA9IDIwO1xyXG4vLyBBIGxpc3Qgb2Ygc3Vic3RyaW5ncyBvZiBDU1MgcHJvcGVydGllcyB1c2VkIHRvIGZpbmQgdHJhbnNpdGlvbiBldmVudHMgdGhhdFxyXG4vLyBtaWdodCBhZmZlY3QgZGltZW5zaW9ucyBvZiBvYnNlcnZlZCBlbGVtZW50cy5cclxudmFyIHRyYW5zaXRpb25LZXlzID0gWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnLCAnd2lkdGgnLCAnaGVpZ2h0JywgJ3NpemUnLCAnd2VpZ2h0J107XHJcbi8vIENoZWNrIGlmIE11dGF0aW9uT2JzZXJ2ZXIgaXMgYXZhaWxhYmxlLlxyXG52YXIgbXV0YXRpb25PYnNlcnZlclN1cHBvcnRlZCA9IHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJztcclxuLyoqXHJcbiAqIFNpbmdsZXRvbiBjb250cm9sbGVyIGNsYXNzIHdoaWNoIGhhbmRsZXMgdXBkYXRlcyBvZiBSZXNpemVPYnNlcnZlciBpbnN0YW5jZXMuXHJcbiAqL1xyXG52YXIgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIoKSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgRE9NIGxpc3RlbmVycyBoYXZlIGJlZW4gYWRkZWQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZSB7Ym9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmNvbm5lY3RlZF8gPSBmYWxzZTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUZWxscyB0aGF0IGNvbnRyb2xsZXIgaGFzIHN1YnNjcmliZWQgZm9yIE11dGF0aW9uIEV2ZW50cy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtib29sZWFufVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubXV0YXRpb25FdmVudHNBZGRlZF8gPSBmYWxzZTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBLZWVwcyByZWZlcmVuY2UgdG8gdGhlIGluc3RhbmNlIG9mIE11dGF0aW9uT2JzZXJ2ZXIuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZSB7TXV0YXRpb25PYnNlcnZlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm11dGF0aW9uc09ic2VydmVyXyA9IG51bGw7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQSBsaXN0IG9mIGNvbm5lY3RlZCBvYnNlcnZlcnMuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAcHJpdmF0ZSB7QXJyYXk8UmVzaXplT2JzZXJ2ZXJTUEk+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMub2JzZXJ2ZXJzXyA9IFtdO1xyXG4gICAgICAgIHRoaXMub25UcmFuc2l0aW9uRW5kXyA9IHRoaXMub25UcmFuc2l0aW9uRW5kXy5iaW5kKHRoaXMpO1xyXG4gICAgICAgIHRoaXMucmVmcmVzaCA9IHRocm90dGxlKHRoaXMucmVmcmVzaC5iaW5kKHRoaXMpLCBSRUZSRVNIX0RFTEFZKTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBvYnNlcnZlciB0byBvYnNlcnZlcnMgbGlzdC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1Jlc2l6ZU9ic2VydmVyU1BJfSBvYnNlcnZlciAtIE9ic2VydmVyIHRvIGJlIGFkZGVkLlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUuYWRkT2JzZXJ2ZXIgPSBmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICBpZiAoIX50aGlzLm9ic2VydmVyc18uaW5kZXhPZihvYnNlcnZlcikpIHtcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnNfLnB1c2gob2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBBZGQgbGlzdGVuZXJzIGlmIHRoZXkgaGF2ZW4ndCBiZWVuIGFkZGVkIHlldC5cclxuICAgICAgICBpZiAoIXRoaXMuY29ubmVjdGVkXykge1xyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3RfKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBvYnNlcnZlciBmcm9tIG9ic2VydmVycyBsaXN0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJTUEl9IG9ic2VydmVyIC0gT2JzZXJ2ZXIgdG8gYmUgcmVtb3ZlZC5cclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLnJlbW92ZU9ic2VydmVyID0gZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgdmFyIG9ic2VydmVycyA9IHRoaXMub2JzZXJ2ZXJzXztcclxuICAgICAgICB2YXIgaW5kZXggPSBvYnNlcnZlcnMuaW5kZXhPZihvYnNlcnZlcik7XHJcbiAgICAgICAgLy8gUmVtb3ZlIG9ic2VydmVyIGlmIGl0J3MgcHJlc2VudCBpbiByZWdpc3RyeS5cclxuICAgICAgICBpZiAofmluZGV4KSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBSZW1vdmUgbGlzdGVuZXJzIGlmIGNvbnRyb2xsZXIgaGFzIG5vIGNvbm5lY3RlZCBvYnNlcnZlcnMuXHJcbiAgICAgICAgaWYgKCFvYnNlcnZlcnMubGVuZ3RoICYmIHRoaXMuY29ubmVjdGVkXykge1xyXG4gICAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3RfKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogSW52b2tlcyB0aGUgdXBkYXRlIG9mIG9ic2VydmVycy4gSXQgd2lsbCBjb250aW51ZSBydW5uaW5nIHVwZGF0ZXMgaW5zb2ZhclxyXG4gICAgICogaXQgZGV0ZWN0cyBjaGFuZ2VzLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLnJlZnJlc2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGNoYW5nZXNEZXRlY3RlZCA9IHRoaXMudXBkYXRlT2JzZXJ2ZXJzXygpO1xyXG4gICAgICAgIC8vIENvbnRpbnVlIHJ1bm5pbmcgdXBkYXRlcyBpZiBjaGFuZ2VzIGhhdmUgYmVlbiBkZXRlY3RlZCBhcyB0aGVyZSBtaWdodFxyXG4gICAgICAgIC8vIGJlIGZ1dHVyZSBvbmVzIGNhdXNlZCBieSBDU1MgdHJhbnNpdGlvbnMuXHJcbiAgICAgICAgaWYgKGNoYW5nZXNEZXRlY3RlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnJlZnJlc2goKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIGV2ZXJ5IG9ic2VydmVyIGZyb20gb2JzZXJ2ZXJzIGxpc3QgYW5kIG5vdGlmaWVzIHRoZW0gb2YgcXVldWVkXHJcbiAgICAgKiBlbnRyaWVzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBcInRydWVcIiBpZiBhbnkgb2JzZXJ2ZXIgaGFzIGRldGVjdGVkIGNoYW5nZXMgaW5cclxuICAgICAqICAgICAgZGltZW5zaW9ucyBvZiBpdCdzIGVsZW1lbnRzLlxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLnVwZGF0ZU9ic2VydmVyc18gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gQ29sbGVjdCBvYnNlcnZlcnMgdGhhdCBoYXZlIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgICAgdmFyIGFjdGl2ZU9ic2VydmVycyA9IHRoaXMub2JzZXJ2ZXJzXy5maWx0ZXIoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZlci5nYXRoZXJBY3RpdmUoKSwgb2JzZXJ2ZXIuaGFzQWN0aXZlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gRGVsaXZlciBub3RpZmljYXRpb25zIGluIGEgc2VwYXJhdGUgY3ljbGUgaW4gb3JkZXIgdG8gYXZvaWQgYW55XHJcbiAgICAgICAgLy8gY29sbGlzaW9ucyBiZXR3ZWVuIG9ic2VydmVycywgZS5nLiB3aGVuIG11bHRpcGxlIGluc3RhbmNlcyBvZlxyXG4gICAgICAgIC8vIFJlc2l6ZU9ic2VydmVyIGFyZSB0cmFja2luZyB0aGUgc2FtZSBlbGVtZW50IGFuZCB0aGUgY2FsbGJhY2sgb2Ygb25lXHJcbiAgICAgICAgLy8gb2YgdGhlbSBjaGFuZ2VzIGNvbnRlbnQgZGltZW5zaW9ucyBvZiB0aGUgb2JzZXJ2ZWQgdGFyZ2V0LiBTb21ldGltZXNcclxuICAgICAgICAvLyB0aGlzIG1heSByZXN1bHQgaW4gbm90aWZpY2F0aW9ucyBiZWluZyBibG9ja2VkIGZvciB0aGUgcmVzdCBvZiBvYnNlcnZlcnMuXHJcbiAgICAgICAgYWN0aXZlT2JzZXJ2ZXJzLmZvckVhY2goZnVuY3Rpb24gKG9ic2VydmVyKSB7IHJldHVybiBvYnNlcnZlci5icm9hZGNhc3RBY3RpdmUoKTsgfSk7XHJcbiAgICAgICAgcmV0dXJuIGFjdGl2ZU9ic2VydmVycy5sZW5ndGggPiAwO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZXMgRE9NIGxpc3RlbmVycy5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUuY29ubmVjdF8gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gRG8gbm90aGluZyBpZiBydW5uaW5nIGluIGEgbm9uLWJyb3dzZXIgZW52aXJvbm1lbnQgb3IgaWYgbGlzdGVuZXJzXHJcbiAgICAgICAgLy8gaGF2ZSBiZWVuIGFscmVhZHkgYWRkZWQuXHJcbiAgICAgICAgaWYgKCFpc0Jyb3dzZXIgfHwgdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gU3Vic2NyaXB0aW9uIHRvIHRoZSBcIlRyYW5zaXRpb25lbmRcIiBldmVudCBpcyB1c2VkIGFzIGEgd29ya2Fyb3VuZCBmb3JcclxuICAgICAgICAvLyBkZWxheWVkIHRyYW5zaXRpb25zLiBUaGlzIHdheSBpdCdzIHBvc3NpYmxlIHRvIGNhcHR1cmUgYXQgbGVhc3QgdGhlXHJcbiAgICAgICAgLy8gZmluYWwgc3RhdGUgb2YgYW4gZWxlbWVudC5cclxuICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgdGhpcy5vblRyYW5zaXRpb25FbmRfKTtcclxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICBpZiAobXV0YXRpb25PYnNlcnZlclN1cHBvcnRlZCkge1xyXG4gICAgICAgICAgICB0aGlzLm11dGF0aW9uc09ic2VydmVyXyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKHRoaXMucmVmcmVzaCk7XHJcbiAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfLm9ic2VydmUoZG9jdW1lbnQsIHtcclxuICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBjaGlsZExpc3Q6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgc3VidHJlZTogdHJ1ZVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTVN1YnRyZWVNb2RpZmllZCcsIHRoaXMucmVmcmVzaCk7XHJcbiAgICAgICAgICAgIHRoaXMubXV0YXRpb25FdmVudHNBZGRlZF8gPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbm5lY3RlZF8gPSB0cnVlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBET00gbGlzdGVuZXJzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS5kaXNjb25uZWN0XyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHJ1bm5pbmcgaW4gYSBub24tYnJvd3NlciBlbnZpcm9ubWVudCBvciBpZiBsaXN0ZW5lcnNcclxuICAgICAgICAvLyBoYXZlIGJlZW4gYWxyZWFkeSByZW1vdmVkLlxyXG4gICAgICAgIGlmICghaXNCcm93c2VyIHx8ICF0aGlzLmNvbm5lY3RlZF8pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgdGhpcy5vblRyYW5zaXRpb25FbmRfKTtcclxuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICBpZiAodGhpcy5tdXRhdGlvbnNPYnNlcnZlcl8pIHtcclxuICAgICAgICAgICAgdGhpcy5tdXRhdGlvbnNPYnNlcnZlcl8uZGlzY29ubmVjdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXykge1xyXG4gICAgICAgICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdET01TdWJ0cmVlTW9kaWZpZWQnLCB0aGlzLnJlZnJlc2gpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm11dGF0aW9uc09ic2VydmVyXyA9IG51bGw7XHJcbiAgICAgICAgdGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGVkXyA9IGZhbHNlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogXCJUcmFuc2l0aW9uZW5kXCIgZXZlbnQgaGFuZGxlci5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICogQHBhcmFtIHtUcmFuc2l0aW9uRXZlbnR9IGV2ZW50XHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS5vblRyYW5zaXRpb25FbmRfID0gZnVuY3Rpb24gKF9hKSB7XHJcbiAgICAgICAgdmFyIF9iID0gX2EucHJvcGVydHlOYW1lLCBwcm9wZXJ0eU5hbWUgPSBfYiA9PT0gdm9pZCAwID8gJycgOiBfYjtcclxuICAgICAgICAvLyBEZXRlY3Qgd2hldGhlciB0cmFuc2l0aW9uIG1heSBhZmZlY3QgZGltZW5zaW9ucyBvZiBhbiBlbGVtZW50LlxyXG4gICAgICAgIHZhciBpc1JlZmxvd1Byb3BlcnR5ID0gdHJhbnNpdGlvbktleXMuc29tZShmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiAhIX5wcm9wZXJ0eU5hbWUuaW5kZXhPZihrZXkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGlmIChpc1JlZmxvd1Byb3BlcnR5KSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgaW5zdGFuY2Ugb2YgdGhlIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIuZ2V0SW5zdGFuY2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmluc3RhbmNlXykge1xyXG4gICAgICAgICAgICB0aGlzLmluc3RhbmNlXyA9IG5ldyBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2VfO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogSG9sZHMgcmVmZXJlbmNlIHRvIHRoZSBjb250cm9sbGVyJ3MgaW5zdGFuY2UuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGUge1Jlc2l6ZU9ic2VydmVyQ29udHJvbGxlcn1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLmluc3RhbmNlXyA9IG51bGw7XHJcbiAgICByZXR1cm4gUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyO1xyXG59KCkpO1xuXG4vKipcclxuICogRGVmaW5lcyBub24td3JpdGFibGUvZW51bWVyYWJsZSBwcm9wZXJ0aWVzIG9mIHRoZSBwcm92aWRlZCB0YXJnZXQgb2JqZWN0LlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0IC0gT2JqZWN0IGZvciB3aGljaCB0byBkZWZpbmUgcHJvcGVydGllcy5cclxuICogQHBhcmFtIHtPYmplY3R9IHByb3BzIC0gUHJvcGVydGllcyB0byBiZSBkZWZpbmVkLlxyXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBUYXJnZXQgb2JqZWN0LlxyXG4gKi9cclxudmFyIGRlZmluZUNvbmZpZ3VyYWJsZSA9IChmdW5jdGlvbiAodGFyZ2V0LCBwcm9wcykge1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IE9iamVjdC5rZXlzKHByb3BzKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIga2V5ID0gX2FbX2ldO1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwge1xyXG4gICAgICAgICAgICB2YWx1ZTogcHJvcHNba2V5XSxcclxuICAgICAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXHJcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGFyZ2V0O1xyXG59KTtcblxuLyoqXHJcbiAqIFJldHVybnMgdGhlIGdsb2JhbCBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcclxuICogQHJldHVybnMge09iamVjdH1cclxuICovXHJcbnZhciBnZXRXaW5kb3dPZiA9IChmdW5jdGlvbiAodGFyZ2V0KSB7XHJcbiAgICAvLyBBc3N1bWUgdGhhdCB0aGUgZWxlbWVudCBpcyBhbiBpbnN0YW5jZSBvZiBOb2RlLCB3aGljaCBtZWFucyB0aGF0IGl0XHJcbiAgICAvLyBoYXMgdGhlIFwib3duZXJEb2N1bWVudFwiIHByb3BlcnR5IGZyb20gd2hpY2ggd2UgY2FuIHJldHJpZXZlIGFcclxuICAgIC8vIGNvcnJlc3BvbmRpbmcgZ2xvYmFsIG9iamVjdC5cclxuICAgIHZhciBvd25lckdsb2JhbCA9IHRhcmdldCAmJiB0YXJnZXQub3duZXJEb2N1bWVudCAmJiB0YXJnZXQub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztcclxuICAgIC8vIFJldHVybiB0aGUgbG9jYWwgZ2xvYmFsIG9iamVjdCBpZiBpdCdzIG5vdCBwb3NzaWJsZSBleHRyYWN0IG9uZSBmcm9tXHJcbiAgICAvLyBwcm92aWRlZCBlbGVtZW50LlxyXG4gICAgcmV0dXJuIG93bmVyR2xvYmFsIHx8IGdsb2JhbCQxO1xyXG59KTtcblxuLy8gUGxhY2Vob2xkZXIgb2YgYW4gZW1wdHkgY29udGVudCByZWN0YW5nbGUuXHJcbnZhciBlbXB0eVJlY3QgPSBjcmVhdGVSZWN0SW5pdCgwLCAwLCAwLCAwKTtcclxuLyoqXHJcbiAqIENvbnZlcnRzIHByb3ZpZGVkIHN0cmluZyB0byBhIG51bWJlci5cclxuICpcclxuICogQHBhcmFtIHtudW1iZXJ8c3RyaW5nfSB2YWx1ZVxyXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gKi9cclxuZnVuY3Rpb24gdG9GbG9hdCh2YWx1ZSkge1xyXG4gICAgcmV0dXJuIHBhcnNlRmxvYXQodmFsdWUpIHx8IDA7XHJcbn1cclxuLyoqXHJcbiAqIEV4dHJhY3RzIGJvcmRlcnMgc2l6ZSBmcm9tIHByb3ZpZGVkIHN0eWxlcy5cclxuICpcclxuICogQHBhcmFtIHtDU1NTdHlsZURlY2xhcmF0aW9ufSBzdHlsZXNcclxuICogQHBhcmFtIHsuLi5zdHJpbmd9IHBvc2l0aW9ucyAtIEJvcmRlcnMgcG9zaXRpb25zICh0b3AsIHJpZ2h0LCAuLi4pXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCb3JkZXJzU2l6ZShzdHlsZXMpIHtcclxuICAgIHZhciBwb3NpdGlvbnMgPSBbXTtcclxuICAgIGZvciAodmFyIF9pID0gMTsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgcG9zaXRpb25zW19pIC0gMV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHBvc2l0aW9ucy5yZWR1Y2UoZnVuY3Rpb24gKHNpemUsIHBvc2l0aW9uKSB7XHJcbiAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVzWydib3JkZXItJyArIHBvc2l0aW9uICsgJy13aWR0aCddO1xyXG4gICAgICAgIHJldHVybiBzaXplICsgdG9GbG9hdCh2YWx1ZSk7XHJcbiAgICB9LCAwKTtcclxufVxyXG4vKipcclxuICogRXh0cmFjdHMgcGFkZGluZ3Mgc2l6ZXMgZnJvbSBwcm92aWRlZCBzdHlsZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7Q1NTU3R5bGVEZWNsYXJhdGlvbn0gc3R5bGVzXHJcbiAqIEByZXR1cm5zIHtPYmplY3R9IFBhZGRpbmdzIGJveC5cclxuICovXHJcbmZ1bmN0aW9uIGdldFBhZGRpbmdzKHN0eWxlcykge1xyXG4gICAgdmFyIHBvc2l0aW9ucyA9IFsndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsICdsZWZ0J107XHJcbiAgICB2YXIgcGFkZGluZ3MgPSB7fTtcclxuICAgIGZvciAodmFyIF9pID0gMCwgcG9zaXRpb25zXzEgPSBwb3NpdGlvbnM7IF9pIDwgcG9zaXRpb25zXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgdmFyIHBvc2l0aW9uID0gcG9zaXRpb25zXzFbX2ldO1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IHN0eWxlc1sncGFkZGluZy0nICsgcG9zaXRpb25dO1xyXG4gICAgICAgIHBhZGRpbmdzW3Bvc2l0aW9uXSA9IHRvRmxvYXQodmFsdWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHBhZGRpbmdzO1xyXG59XHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIGNvbnRlbnQgcmVjdGFuZ2xlIG9mIHByb3ZpZGVkIFNWRyBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge1NWR0dyYXBoaWNzRWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCBjb250ZW50IHJlY3RhbmdsZSBvZiB3aGljaCBuZWVkc1xyXG4gKiAgICAgIHRvIGJlIGNhbGN1bGF0ZWQuXHJcbiAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldFNWR0NvbnRlbnRSZWN0KHRhcmdldCkge1xyXG4gICAgdmFyIGJib3ggPSB0YXJnZXQuZ2V0QkJveCgpO1xyXG4gICAgcmV0dXJuIGNyZWF0ZVJlY3RJbml0KDAsIDAsIGJib3gud2lkdGgsIGJib3guaGVpZ2h0KTtcclxufVxyXG4vKipcclxuICogQ2FsY3VsYXRlcyBjb250ZW50IHJlY3RhbmdsZSBvZiBwcm92aWRlZCBIVE1MRWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCBmb3Igd2hpY2ggdG8gY2FsY3VsYXRlIHRoZSBjb250ZW50IHJlY3RhbmdsZS5cclxuICogQHJldHVybnMge0RPTVJlY3RJbml0fVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0SFRNTEVsZW1lbnRDb250ZW50UmVjdCh0YXJnZXQpIHtcclxuICAgIC8vIENsaWVudCB3aWR0aCAmIGhlaWdodCBwcm9wZXJ0aWVzIGNhbid0IGJlXHJcbiAgICAvLyB1c2VkIGV4Y2x1c2l2ZWx5IGFzIHRoZXkgcHJvdmlkZSByb3VuZGVkIHZhbHVlcy5cclxuICAgIHZhciBjbGllbnRXaWR0aCA9IHRhcmdldC5jbGllbnRXaWR0aCwgY2xpZW50SGVpZ2h0ID0gdGFyZ2V0LmNsaWVudEhlaWdodDtcclxuICAgIC8vIEJ5IHRoaXMgY29uZGl0aW9uIHdlIGNhbiBjYXRjaCBhbGwgbm9uLXJlcGxhY2VkIGlubGluZSwgaGlkZGVuIGFuZFxyXG4gICAgLy8gZGV0YWNoZWQgZWxlbWVudHMuIFRob3VnaCBlbGVtZW50cyB3aXRoIHdpZHRoICYgaGVpZ2h0IHByb3BlcnRpZXMgbGVzc1xyXG4gICAgLy8gdGhhbiAwLjUgd2lsbCBiZSBkaXNjYXJkZWQgYXMgd2VsbC5cclxuICAgIC8vXHJcbiAgICAvLyBXaXRob3V0IGl0IHdlIHdvdWxkIG5lZWQgdG8gaW1wbGVtZW50IHNlcGFyYXRlIG1ldGhvZHMgZm9yIGVhY2ggb2ZcclxuICAgIC8vIHRob3NlIGNhc2VzIGFuZCBpdCdzIG5vdCBwb3NzaWJsZSB0byBwZXJmb3JtIGEgcHJlY2lzZSBhbmQgcGVyZm9ybWFuY2VcclxuICAgIC8vIGVmZmVjdGl2ZSB0ZXN0IGZvciBoaWRkZW4gZWxlbWVudHMuIEUuZy4gZXZlbiBqUXVlcnkncyAnOnZpc2libGUnIGZpbHRlclxyXG4gICAgLy8gZ2l2ZXMgd3JvbmcgcmVzdWx0cyBmb3IgZWxlbWVudHMgd2l0aCB3aWR0aCAmIGhlaWdodCBsZXNzIHRoYW4gMC41LlxyXG4gICAgaWYgKCFjbGllbnRXaWR0aCAmJiAhY2xpZW50SGVpZ2h0KSB7XHJcbiAgICAgICAgcmV0dXJuIGVtcHR5UmVjdDtcclxuICAgIH1cclxuICAgIHZhciBzdHlsZXMgPSBnZXRXaW5kb3dPZih0YXJnZXQpLmdldENvbXB1dGVkU3R5bGUodGFyZ2V0KTtcclxuICAgIHZhciBwYWRkaW5ncyA9IGdldFBhZGRpbmdzKHN0eWxlcyk7XHJcbiAgICB2YXIgaG9yaXpQYWQgPSBwYWRkaW5ncy5sZWZ0ICsgcGFkZGluZ3MucmlnaHQ7XHJcbiAgICB2YXIgdmVydFBhZCA9IHBhZGRpbmdzLnRvcCArIHBhZGRpbmdzLmJvdHRvbTtcclxuICAgIC8vIENvbXB1dGVkIHN0eWxlcyBvZiB3aWR0aCAmIGhlaWdodCBhcmUgYmVpbmcgdXNlZCBiZWNhdXNlIHRoZXkgYXJlIHRoZVxyXG4gICAgLy8gb25seSBkaW1lbnNpb25zIGF2YWlsYWJsZSB0byBKUyB0aGF0IGNvbnRhaW4gbm9uLXJvdW5kZWQgdmFsdWVzLiBJdCBjb3VsZFxyXG4gICAgLy8gYmUgcG9zc2libGUgdG8gdXRpbGl6ZSB0aGUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGlmIG9ubHkgaXQncyBkYXRhIHdhc24ndFxyXG4gICAgLy8gYWZmZWN0ZWQgYnkgQ1NTIHRyYW5zZm9ybWF0aW9ucyBsZXQgYWxvbmUgcGFkZGluZ3MsIGJvcmRlcnMgYW5kIHNjcm9sbCBiYXJzLlxyXG4gICAgdmFyIHdpZHRoID0gdG9GbG9hdChzdHlsZXMud2lkdGgpLCBoZWlnaHQgPSB0b0Zsb2F0KHN0eWxlcy5oZWlnaHQpO1xyXG4gICAgLy8gV2lkdGggJiBoZWlnaHQgaW5jbHVkZSBwYWRkaW5ncyBhbmQgYm9yZGVycyB3aGVuIHRoZSAnYm9yZGVyLWJveCcgYm94XHJcbiAgICAvLyBtb2RlbCBpcyBhcHBsaWVkIChleGNlcHQgZm9yIElFKS5cclxuICAgIGlmIChzdHlsZXMuYm94U2l6aW5nID09PSAnYm9yZGVyLWJveCcpIHtcclxuICAgICAgICAvLyBGb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgcmVxdWlyZWQgdG8gaGFuZGxlIEludGVybmV0IEV4cGxvcmVyIHdoaWNoXHJcbiAgICAgICAgLy8gZG9lc24ndCBpbmNsdWRlIHBhZGRpbmdzIGFuZCBib3JkZXJzIHRvIGNvbXB1dGVkIENTUyBkaW1lbnNpb25zLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gV2UgY2FuIHNheSB0aGF0IGlmIENTUyBkaW1lbnNpb25zICsgcGFkZGluZ3MgYXJlIGVxdWFsIHRvIHRoZSBcImNsaWVudFwiXHJcbiAgICAgICAgLy8gcHJvcGVydGllcyB0aGVuIGl0J3MgZWl0aGVyIElFLCBhbmQgdGh1cyB3ZSBkb24ndCBuZWVkIHRvIHN1YnRyYWN0XHJcbiAgICAgICAgLy8gYW55dGhpbmcsIG9yIGFuIGVsZW1lbnQgbWVyZWx5IGRvZXNuJ3QgaGF2ZSBwYWRkaW5ncy9ib3JkZXJzIHN0eWxlcy5cclxuICAgICAgICBpZiAoTWF0aC5yb3VuZCh3aWR0aCArIGhvcml6UGFkKSAhPT0gY2xpZW50V2lkdGgpIHtcclxuICAgICAgICAgICAgd2lkdGggLT0gZ2V0Qm9yZGVyc1NpemUoc3R5bGVzLCAnbGVmdCcsICdyaWdodCcpICsgaG9yaXpQYWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChNYXRoLnJvdW5kKGhlaWdodCArIHZlcnRQYWQpICE9PSBjbGllbnRIZWlnaHQpIHtcclxuICAgICAgICAgICAgaGVpZ2h0IC09IGdldEJvcmRlcnNTaXplKHN0eWxlcywgJ3RvcCcsICdib3R0b20nKSArIHZlcnRQYWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gRm9sbG93aW5nIHN0ZXBzIGNhbid0IGJlIGFwcGxpZWQgdG8gdGhlIGRvY3VtZW50J3Mgcm9vdCBlbGVtZW50IGFzIGl0c1xyXG4gICAgLy8gY2xpZW50W1dpZHRoL0hlaWdodF0gcHJvcGVydGllcyByZXByZXNlbnQgdmlld3BvcnQgYXJlYSBvZiB0aGUgd2luZG93LlxyXG4gICAgLy8gQmVzaWRlcywgaXQncyBhcyB3ZWxsIG5vdCBuZWNlc3NhcnkgYXMgdGhlIDxodG1sPiBpdHNlbGYgbmVpdGhlciBoYXNcclxuICAgIC8vIHJlbmRlcmVkIHNjcm9sbCBiYXJzIG5vciBpdCBjYW4gYmUgY2xpcHBlZC5cclxuICAgIGlmICghaXNEb2N1bWVudEVsZW1lbnQodGFyZ2V0KSkge1xyXG4gICAgICAgIC8vIEluIHNvbWUgYnJvd3NlcnMgKG9ubHkgaW4gRmlyZWZveCwgYWN0dWFsbHkpIENTUyB3aWR0aCAmIGhlaWdodFxyXG4gICAgICAgIC8vIGluY2x1ZGUgc2Nyb2xsIGJhcnMgc2l6ZSB3aGljaCBjYW4gYmUgcmVtb3ZlZCBhdCB0aGlzIHN0ZXAgYXMgc2Nyb2xsXHJcbiAgICAgICAgLy8gYmFycyBhcmUgdGhlIG9ubHkgZGlmZmVyZW5jZSBiZXR3ZWVuIHJvdW5kZWQgZGltZW5zaW9ucyArIHBhZGRpbmdzXHJcbiAgICAgICAgLy8gYW5kIFwiY2xpZW50XCIgcHJvcGVydGllcywgdGhvdWdoIHRoYXQgaXMgbm90IGFsd2F5cyB0cnVlIGluIENocm9tZS5cclxuICAgICAgICB2YXIgdmVydFNjcm9sbGJhciA9IE1hdGgucm91bmQod2lkdGggKyBob3JpelBhZCkgLSBjbGllbnRXaWR0aDtcclxuICAgICAgICB2YXIgaG9yaXpTY3JvbGxiYXIgPSBNYXRoLnJvdW5kKGhlaWdodCArIHZlcnRQYWQpIC0gY2xpZW50SGVpZ2h0O1xyXG4gICAgICAgIC8vIENocm9tZSBoYXMgYSByYXRoZXIgd2VpcmQgcm91bmRpbmcgb2YgXCJjbGllbnRcIiBwcm9wZXJ0aWVzLlxyXG4gICAgICAgIC8vIEUuZy4gZm9yIGFuIGVsZW1lbnQgd2l0aCBjb250ZW50IHdpZHRoIG9mIDMxNC4ycHggaXQgc29tZXRpbWVzIGdpdmVzXHJcbiAgICAgICAgLy8gdGhlIGNsaWVudCB3aWR0aCBvZiAzMTVweCBhbmQgZm9yIHRoZSB3aWR0aCBvZiAzMTQuN3B4IGl0IG1heSBnaXZlXHJcbiAgICAgICAgLy8gMzE0cHguIEFuZCBpdCBkb2Vzbid0IGhhcHBlbiBhbGwgdGhlIHRpbWUuIFNvIGp1c3QgaWdub3JlIHRoaXMgZGVsdGFcclxuICAgICAgICAvLyBhcyBhIG5vbi1yZWxldmFudC5cclxuICAgICAgICBpZiAoTWF0aC5hYnModmVydFNjcm9sbGJhcikgIT09IDEpIHtcclxuICAgICAgICAgICAgd2lkdGggLT0gdmVydFNjcm9sbGJhcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKE1hdGguYWJzKGhvcml6U2Nyb2xsYmFyKSAhPT0gMSkge1xyXG4gICAgICAgICAgICBoZWlnaHQgLT0gaG9yaXpTY3JvbGxiYXI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNyZWF0ZVJlY3RJbml0KHBhZGRpbmdzLmxlZnQsIHBhZGRpbmdzLnRvcCwgd2lkdGgsIGhlaWdodCk7XHJcbn1cclxuLyoqXHJcbiAqIENoZWNrcyB3aGV0aGVyIHByb3ZpZGVkIGVsZW1lbnQgaXMgYW4gaW5zdGFuY2Ugb2YgdGhlIFNWR0dyYXBoaWNzRWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRvIGJlIGNoZWNrZWQuXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxudmFyIGlzU1ZHR3JhcGhpY3NFbGVtZW50ID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIC8vIFNvbWUgYnJvd3NlcnMsIG5hbWVseSBJRSBhbmQgRWRnZSwgZG9uJ3QgaGF2ZSB0aGUgU1ZHR3JhcGhpY3NFbGVtZW50XHJcbiAgICAvLyBpbnRlcmZhY2UuXHJcbiAgICBpZiAodHlwZW9mIFNWR0dyYXBoaWNzRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCkgeyByZXR1cm4gdGFyZ2V0IGluc3RhbmNlb2YgZ2V0V2luZG93T2YodGFyZ2V0KS5TVkdHcmFwaGljc0VsZW1lbnQ7IH07XHJcbiAgICB9XHJcbiAgICAvLyBJZiBpdCdzIHNvLCB0aGVuIGNoZWNrIHRoYXQgZWxlbWVudCBpcyBhdCBsZWFzdCBhbiBpbnN0YW5jZSBvZiB0aGVcclxuICAgIC8vIFNWR0VsZW1lbnQgYW5kIHRoYXQgaXQgaGFzIHRoZSBcImdldEJCb3hcIiBtZXRob2QuXHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXh0cmEtcGFyZW5zXHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCkgeyByZXR1cm4gKHRhcmdldCBpbnN0YW5jZW9mIGdldFdpbmRvd09mKHRhcmdldCkuU1ZHRWxlbWVudCAmJlxyXG4gICAgICAgIHR5cGVvZiB0YXJnZXQuZ2V0QkJveCA9PT0gJ2Z1bmN0aW9uJyk7IH07XHJcbn0pKCk7XHJcbi8qKlxyXG4gKiBDaGVja3Mgd2hldGhlciBwcm92aWRlZCBlbGVtZW50IGlzIGEgZG9jdW1lbnQgZWxlbWVudCAoPGh0bWw+KS5cclxuICpcclxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRvIGJlIGNoZWNrZWQuXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gaXNEb2N1bWVudEVsZW1lbnQodGFyZ2V0KSB7XHJcbiAgICByZXR1cm4gdGFyZ2V0ID09PSBnZXRXaW5kb3dPZih0YXJnZXQpLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcclxufVxyXG4vKipcclxuICogQ2FsY3VsYXRlcyBhbiBhcHByb3ByaWF0ZSBjb250ZW50IHJlY3RhbmdsZSBmb3IgcHJvdmlkZWQgaHRtbCBvciBzdmcgZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IGNvbnRlbnQgcmVjdGFuZ2xlIG9mIHdoaWNoIG5lZWRzIHRvIGJlIGNhbGN1bGF0ZWQuXHJcbiAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldENvbnRlbnRSZWN0KHRhcmdldCkge1xyXG4gICAgaWYgKCFpc0Jyb3dzZXIpIHtcclxuICAgICAgICByZXR1cm4gZW1wdHlSZWN0O1xyXG4gICAgfVxyXG4gICAgaWYgKGlzU1ZHR3JhcGhpY3NFbGVtZW50KHRhcmdldCkpIHtcclxuICAgICAgICByZXR1cm4gZ2V0U1ZHQ29udGVudFJlY3QodGFyZ2V0KTtcclxuICAgIH1cclxuICAgIHJldHVybiBnZXRIVE1MRWxlbWVudENvbnRlbnRSZWN0KHRhcmdldCk7XHJcbn1cclxuLyoqXHJcbiAqIENyZWF0ZXMgcmVjdGFuZ2xlIHdpdGggYW4gaW50ZXJmYWNlIG9mIHRoZSBET01SZWN0UmVhZE9ubHkuXHJcbiAqIFNwZWM6IGh0dHBzOi8vZHJhZnRzLmZ4dGYub3JnL2dlb21ldHJ5LyNkb21yZWN0cmVhZG9ubHlcclxuICpcclxuICogQHBhcmFtIHtET01SZWN0SW5pdH0gcmVjdEluaXQgLSBPYmplY3Qgd2l0aCByZWN0YW5nbGUncyB4L3kgY29vcmRpbmF0ZXMgYW5kIGRpbWVuc2lvbnMuXHJcbiAqIEByZXR1cm5zIHtET01SZWN0UmVhZE9ubHl9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVSZWFkT25seVJlY3QoX2EpIHtcclxuICAgIHZhciB4ID0gX2EueCwgeSA9IF9hLnksIHdpZHRoID0gX2Eud2lkdGgsIGhlaWdodCA9IF9hLmhlaWdodDtcclxuICAgIC8vIElmIERPTVJlY3RSZWFkT25seSBpcyBhdmFpbGFibGUgdXNlIGl0IGFzIGEgcHJvdG90eXBlIGZvciB0aGUgcmVjdGFuZ2xlLlxyXG4gICAgdmFyIENvbnN0ciA9IHR5cGVvZiBET01SZWN0UmVhZE9ubHkgIT09ICd1bmRlZmluZWQnID8gRE9NUmVjdFJlYWRPbmx5IDogT2JqZWN0O1xyXG4gICAgdmFyIHJlY3QgPSBPYmplY3QuY3JlYXRlKENvbnN0ci5wcm90b3R5cGUpO1xyXG4gICAgLy8gUmVjdGFuZ2xlJ3MgcHJvcGVydGllcyBhcmUgbm90IHdyaXRhYmxlIGFuZCBub24tZW51bWVyYWJsZS5cclxuICAgIGRlZmluZUNvbmZpZ3VyYWJsZShyZWN0LCB7XHJcbiAgICAgICAgeDogeCwgeTogeSwgd2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCxcclxuICAgICAgICB0b3A6IHksXHJcbiAgICAgICAgcmlnaHQ6IHggKyB3aWR0aCxcclxuICAgICAgICBib3R0b206IGhlaWdodCArIHksXHJcbiAgICAgICAgbGVmdDogeFxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmVjdDtcclxufVxyXG4vKipcclxuICogQ3JlYXRlcyBET01SZWN0SW5pdCBvYmplY3QgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGRpbWVuc2lvbnMgYW5kIHRoZSB4L3kgY29vcmRpbmF0ZXMuXHJcbiAqIFNwZWM6IGh0dHBzOi8vZHJhZnRzLmZ4dGYub3JnL2dlb21ldHJ5LyNkaWN0ZGVmLWRvbXJlY3Rpbml0XHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB4IC0gWCBjb29yZGluYXRlLlxyXG4gKiBAcGFyYW0ge251bWJlcn0geSAtIFkgY29vcmRpbmF0ZS5cclxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gUmVjdGFuZ2xlJ3Mgd2lkdGguXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgLSBSZWN0YW5nbGUncyBoZWlnaHQuXHJcbiAqIEByZXR1cm5zIHtET01SZWN0SW5pdH1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJlY3RJbml0KHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcclxuICAgIHJldHVybiB7IHg6IHgsIHk6IHksIHdpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHQgfTtcclxufVxuXG4vKipcclxuICogQ2xhc3MgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgY29tcHV0YXRpb25zIG9mIHRoZSBjb250ZW50IHJlY3RhbmdsZSBvZlxyXG4gKiBwcm92aWRlZCBET00gZWxlbWVudCBhbmQgZm9yIGtlZXBpbmcgdHJhY2sgb2YgaXQncyBjaGFuZ2VzLlxyXG4gKi9cclxudmFyIFJlc2l6ZU9ic2VydmF0aW9uID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmF0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCB0byBiZSBvYnNlcnZlZC5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gUmVzaXplT2JzZXJ2YXRpb24odGFyZ2V0KSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQnJvYWRjYXN0ZWQgd2lkdGggb2YgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAdHlwZSB7bnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuYnJvYWRjYXN0V2lkdGggPSAwO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEJyb2FkY2FzdGVkIGhlaWdodCBvZiBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5icm9hZGNhc3RIZWlnaHQgPSAwO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlZmVyZW5jZSB0byB0aGUgbGFzdCBvYnNlcnZlZCBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtET01SZWN0SW5pdH1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmNvbnRlbnRSZWN0XyA9IGNyZWF0ZVJlY3RJbml0KDAsIDAsIDAsIDApO1xyXG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0O1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIGNvbnRlbnQgcmVjdGFuZ2xlIGFuZCB0ZWxscyB3aGV0aGVyIGl0J3Mgd2lkdGggb3IgaGVpZ2h0IHByb3BlcnRpZXNcclxuICAgICAqIGhhdmUgY2hhbmdlZCBzaW5jZSB0aGUgbGFzdCBicm9hZGNhc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmF0aW9uLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgcmVjdCA9IGdldENvbnRlbnRSZWN0KHRoaXMudGFyZ2V0KTtcclxuICAgICAgICB0aGlzLmNvbnRlbnRSZWN0XyA9IHJlY3Q7XHJcbiAgICAgICAgcmV0dXJuIChyZWN0LndpZHRoICE9PSB0aGlzLmJyb2FkY2FzdFdpZHRoIHx8XHJcbiAgICAgICAgICAgIHJlY3QuaGVpZ2h0ICE9PSB0aGlzLmJyb2FkY2FzdEhlaWdodCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzICdicm9hZGNhc3RXaWR0aCcgYW5kICdicm9hZGNhc3RIZWlnaHQnIHByb3BlcnRpZXMgd2l0aCBhIGRhdGFcclxuICAgICAqIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgcHJvcGVydGllcyBvZiB0aGUgbGFzdCBvYnNlcnZlZCBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NUmVjdEluaXR9IExhc3Qgb2JzZXJ2ZWQgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmF0aW9uLnByb3RvdHlwZS5icm9hZGNhc3RSZWN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciByZWN0ID0gdGhpcy5jb250ZW50UmVjdF87XHJcbiAgICAgICAgdGhpcy5icm9hZGNhc3RXaWR0aCA9IHJlY3Qud2lkdGg7XHJcbiAgICAgICAgdGhpcy5icm9hZGNhc3RIZWlnaHQgPSByZWN0LmhlaWdodDtcclxuICAgICAgICByZXR1cm4gcmVjdDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gUmVzaXplT2JzZXJ2YXRpb247XHJcbn0oKSk7XG5cbnZhciBSZXNpemVPYnNlcnZlckVudHJ5ID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmVyRW50cnkuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRoYXQgaXMgYmVpbmcgb2JzZXJ2ZWQuXHJcbiAgICAgKiBAcGFyYW0ge0RPTVJlY3RJbml0fSByZWN0SW5pdCAtIERhdGEgb2YgdGhlIGVsZW1lbnQncyBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gUmVzaXplT2JzZXJ2ZXJFbnRyeSh0YXJnZXQsIHJlY3RJbml0KSB7XHJcbiAgICAgICAgdmFyIGNvbnRlbnRSZWN0ID0gY3JlYXRlUmVhZE9ubHlSZWN0KHJlY3RJbml0KTtcclxuICAgICAgICAvLyBBY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmljYXRpb24gZm9sbG93aW5nIHByb3BlcnRpZXMgYXJlIG5vdCB3cml0YWJsZVxyXG4gICAgICAgIC8vIGFuZCBhcmUgYWxzbyBub3QgZW51bWVyYWJsZSBpbiB0aGUgbmF0aXZlIGltcGxlbWVudGF0aW9uLlxyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gUHJvcGVydHkgYWNjZXNzb3JzIGFyZSBub3QgYmVpbmcgdXNlZCBhcyB0aGV5J2QgcmVxdWlyZSB0byBkZWZpbmUgYVxyXG4gICAgICAgIC8vIHByaXZhdGUgV2Vha01hcCBzdG9yYWdlIHdoaWNoIG1heSBjYXVzZSBtZW1vcnkgbGVha3MgaW4gYnJvd3NlcnMgdGhhdFxyXG4gICAgICAgIC8vIGRvbid0IHN1cHBvcnQgdGhpcyB0eXBlIG9mIGNvbGxlY3Rpb25zLlxyXG4gICAgICAgIGRlZmluZUNvbmZpZ3VyYWJsZSh0aGlzLCB7IHRhcmdldDogdGFyZ2V0LCBjb250ZW50UmVjdDogY29udGVudFJlY3QgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gUmVzaXplT2JzZXJ2ZXJFbnRyeTtcclxufSgpKTtcblxudmFyIFJlc2l6ZU9ic2VydmVyU1BJID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmVyLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDYWxsYmFja30gY2FsbGJhY2sgLSBDYWxsYmFjayBmdW5jdGlvbiB0aGF0IGlzIGludm9rZWRcclxuICAgICAqICAgICAgd2hlbiBvbmUgb2YgdGhlIG9ic2VydmVkIGVsZW1lbnRzIGNoYW5nZXMgaXQncyBjb250ZW50IGRpbWVuc2lvbnMuXHJcbiAgICAgKiBAcGFyYW0ge1Jlc2l6ZU9ic2VydmVyQ29udHJvbGxlcn0gY29udHJvbGxlciAtIENvbnRyb2xsZXIgaW5zdGFuY2Ugd2hpY2hcclxuICAgICAqICAgICAgaXMgcmVzcG9uc2libGUgZm9yIHRoZSB1cGRhdGVzIG9mIG9ic2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtSZXNpemVPYnNlcnZlcn0gY2FsbGJhY2tDdHggLSBSZWZlcmVuY2UgdG8gdGhlIHB1YmxpY1xyXG4gICAgICogICAgICBSZXNpemVPYnNlcnZlciBpbnN0YW5jZSB3aGljaCB3aWxsIGJlIHBhc3NlZCB0byBjYWxsYmFjayBmdW5jdGlvbi5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gUmVzaXplT2JzZXJ2ZXJTUEkoY2FsbGJhY2ssIGNvbnRyb2xsZXIsIGNhbGxiYWNrQ3R4KSB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29sbGVjdGlvbiBvZiByZXNpemUgb2JzZXJ2YXRpb25zIHRoYXQgaGF2ZSBkZXRlY3RlZCBjaGFuZ2VzIGluIGRpbWVuc2lvbnNcclxuICAgICAgICAgKiBvZiBlbGVtZW50cy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtBcnJheTxSZXNpemVPYnNlcnZhdGlvbj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfID0gW107XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVnaXN0cnkgb2YgdGhlIFJlc2l6ZU9ic2VydmF0aW9uIGluc3RhbmNlcy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtNYXA8RWxlbWVudCwgUmVzaXplT2JzZXJ2YXRpb24+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMub2JzZXJ2YXRpb25zXyA9IG5ldyBNYXBTaGltKCk7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgY2FsbGJhY2sgcHJvdmlkZWQgYXMgcGFyYW1ldGVyIDEgaXMgbm90IGEgZnVuY3Rpb24uJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tfID0gY2FsbGJhY2s7XHJcbiAgICAgICAgdGhpcy5jb250cm9sbGVyXyA9IGNvbnRyb2xsZXI7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja0N0eF8gPSBjYWxsYmFja0N0eDtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU3RhcnRzIG9ic2VydmluZyBwcm92aWRlZCBlbGVtZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCB0byBiZSBvYnNlcnZlZC5cclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlclNQSS5wcm90b3R5cGUub2JzZXJ2ZSA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIGN1cnJlbnQgZW52aXJvbm1lbnQgZG9lc24ndCBoYXZlIHRoZSBFbGVtZW50IGludGVyZmFjZS5cclxuICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICEoRWxlbWVudCBpbnN0YW5jZW9mIE9iamVjdCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBnZXRXaW5kb3dPZih0YXJnZXQpLkVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BhcmFtZXRlciAxIGlzIG5vdCBvZiB0eXBlIFwiRWxlbWVudFwiLicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb2JzZXJ2YXRpb25zID0gdGhpcy5vYnNlcnZhdGlvbnNfO1xyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgZWxlbWVudCBpcyBhbHJlYWR5IGJlaW5nIG9ic2VydmVkLlxyXG4gICAgICAgIGlmIChvYnNlcnZhdGlvbnMuaGFzKHRhcmdldCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBvYnNlcnZhdGlvbnMuc2V0KHRhcmdldCwgbmV3IFJlc2l6ZU9ic2VydmF0aW9uKHRhcmdldCkpO1xyXG4gICAgICAgIHRoaXMuY29udHJvbGxlcl8uYWRkT2JzZXJ2ZXIodGhpcyk7XHJcbiAgICAgICAgLy8gRm9yY2UgdGhlIHVwZGF0ZSBvZiBvYnNlcnZhdGlvbnMuXHJcbiAgICAgICAgdGhpcy5jb250cm9sbGVyXy5yZWZyZXNoKCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTdG9wcyBvYnNlcnZpbmcgcHJvdmlkZWQgZWxlbWVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gc3RvcCBvYnNlcnZpbmcuXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLnVub2JzZXJ2ZSA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignMSBhcmd1bWVudCByZXF1aXJlZCwgYnV0IG9ubHkgMCBwcmVzZW50LicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIGN1cnJlbnQgZW52aXJvbm1lbnQgZG9lc24ndCBoYXZlIHRoZSBFbGVtZW50IGludGVyZmFjZS5cclxuICAgICAgICBpZiAodHlwZW9mIEVsZW1lbnQgPT09ICd1bmRlZmluZWQnIHx8ICEoRWxlbWVudCBpbnN0YW5jZW9mIE9iamVjdCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoISh0YXJnZXQgaW5zdGFuY2VvZiBnZXRXaW5kb3dPZih0YXJnZXQpLkVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BhcmFtZXRlciAxIGlzIG5vdCBvZiB0eXBlIFwiRWxlbWVudFwiLicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb2JzZXJ2YXRpb25zID0gdGhpcy5vYnNlcnZhdGlvbnNfO1xyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgZWxlbWVudCBpcyBub3QgYmVpbmcgb2JzZXJ2ZWQuXHJcbiAgICAgICAgaWYgKCFvYnNlcnZhdGlvbnMuaGFzKHRhcmdldCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBvYnNlcnZhdGlvbnMuZGVsZXRlKHRhcmdldCk7XHJcbiAgICAgICAgaWYgKCFvYnNlcnZhdGlvbnMuc2l6ZSkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbnRyb2xsZXJfLnJlbW92ZU9ic2VydmVyKHRoaXMpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFN0b3BzIG9ic2VydmluZyBhbGwgZWxlbWVudHMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuY2xlYXJBY3RpdmUoKTtcclxuICAgICAgICB0aGlzLm9ic2VydmF0aW9uc18uY2xlYXIoKTtcclxuICAgICAgICB0aGlzLmNvbnRyb2xsZXJfLnJlbW92ZU9ic2VydmVyKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ29sbGVjdHMgb2JzZXJ2YXRpb24gaW5zdGFuY2VzIHRoZSBhc3NvY2lhdGVkIGVsZW1lbnQgb2Ygd2hpY2ggaGFzIGNoYW5nZWRcclxuICAgICAqIGl0J3MgY29udGVudCByZWN0YW5nbGUuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5nYXRoZXJBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLmNsZWFyQWN0aXZlKCk7XHJcbiAgICAgICAgdGhpcy5vYnNlcnZhdGlvbnNfLmZvckVhY2goZnVuY3Rpb24gKG9ic2VydmF0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmIChvYnNlcnZhdGlvbi5pc0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfLnB1c2gob2JzZXJ2YXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2VzIGluaXRpYWwgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCBhIGxpc3Qgb2YgUmVzaXplT2JzZXJ2ZXJFbnRyeVxyXG4gICAgICogaW5zdGFuY2VzIGNvbGxlY3RlZCBmcm9tIGFjdGl2ZSByZXNpemUgb2JzZXJ2YXRpb25zLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlclNQSS5wcm90b3R5cGUuYnJvYWRjYXN0QWN0aXZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgb2JzZXJ2ZXIgZG9lc24ndCBoYXZlIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgICAgaWYgKCF0aGlzLmhhc0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGN0eCA9IHRoaXMuY2FsbGJhY2tDdHhfO1xyXG4gICAgICAgIC8vIENyZWF0ZSBSZXNpemVPYnNlcnZlckVudHJ5IGluc3RhbmNlIGZvciBldmVyeSBhY3RpdmUgb2JzZXJ2YXRpb24uXHJcbiAgICAgICAgdmFyIGVudHJpZXMgPSB0aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18ubWFwKGZ1bmN0aW9uIChvYnNlcnZhdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlc2l6ZU9ic2VydmVyRW50cnkob2JzZXJ2YXRpb24udGFyZ2V0LCBvYnNlcnZhdGlvbi5icm9hZGNhc3RSZWN0KCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2tfLmNhbGwoY3R4LCBlbnRyaWVzLCBjdHgpO1xyXG4gICAgICAgIHRoaXMuY2xlYXJBY3RpdmUoKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGUgY29sbGVjdGlvbiBvZiBhY3RpdmUgb2JzZXJ2YXRpb25zLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlclNQSS5wcm90b3R5cGUuY2xlYXJBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfLnNwbGljZSgwKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFRlbGxzIHdoZXRoZXIgb2JzZXJ2ZXIgaGFzIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5oYXNBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlT2JzZXJ2YXRpb25zXy5sZW5ndGggPiAwO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZlclNQSTtcclxufSgpKTtcblxuLy8gUmVnaXN0cnkgb2YgaW50ZXJuYWwgb2JzZXJ2ZXJzLiBJZiBXZWFrTWFwIGlzIG5vdCBhdmFpbGFibGUgdXNlIGN1cnJlbnQgc2hpbVxyXG4vLyBmb3IgdGhlIE1hcCBjb2xsZWN0aW9uIGFzIGl0IGhhcyBhbGwgcmVxdWlyZWQgbWV0aG9kcyBhbmQgYmVjYXVzZSBXZWFrTWFwXHJcbi8vIGNhbid0IGJlIGZ1bGx5IHBvbHlmaWxsZWQgYW55d2F5LlxyXG52YXIgb2JzZXJ2ZXJzID0gdHlwZW9mIFdlYWtNYXAgIT09ICd1bmRlZmluZWQnID8gbmV3IFdlYWtNYXAoKSA6IG5ldyBNYXBTaGltKCk7XHJcbi8qKlxyXG4gKiBSZXNpemVPYnNlcnZlciBBUEkuIEVuY2Fwc3VsYXRlcyB0aGUgUmVzaXplT2JzZXJ2ZXIgU1BJIGltcGxlbWVudGF0aW9uXHJcbiAqIGV4cG9zaW5nIG9ubHkgdGhvc2UgbWV0aG9kcyBhbmQgcHJvcGVydGllcyB0aGF0IGFyZSBkZWZpbmVkIGluIHRoZSBzcGVjLlxyXG4gKi9cclxudmFyIFJlc2l6ZU9ic2VydmVyID0gLyoqIEBjbGFzcyAqLyAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJlc2l6ZU9ic2VydmVyLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDYWxsYmFja30gY2FsbGJhY2sgLSBDYWxsYmFjayB0aGF0IGlzIGludm9rZWQgd2hlblxyXG4gICAgICogICAgICBkaW1lbnNpb25zIG9mIHRoZSBvYnNlcnZlZCBlbGVtZW50cyBjaGFuZ2UuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlc2l6ZU9ic2VydmVyKSkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24uJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCcxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjb250cm9sbGVyID0gUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLmdldEluc3RhbmNlKCk7XHJcbiAgICAgICAgdmFyIG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyU1BJKGNhbGxiYWNrLCBjb250cm9sbGVyLCB0aGlzKTtcclxuICAgICAgICBvYnNlcnZlcnMuc2V0KHRoaXMsIG9ic2VydmVyKTtcclxuICAgIH1cclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZlcjtcclxufSgpKTtcclxuLy8gRXhwb3NlIHB1YmxpYyBtZXRob2RzIG9mIFJlc2l6ZU9ic2VydmVyLlxyXG5bXHJcbiAgICAnb2JzZXJ2ZScsXHJcbiAgICAndW5vYnNlcnZlJyxcclxuICAgICdkaXNjb25uZWN0J1xyXG5dLmZvckVhY2goZnVuY3Rpb24gKG1ldGhvZCkge1xyXG4gICAgUmVzaXplT2JzZXJ2ZXIucHJvdG90eXBlW21ldGhvZF0gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF9hO1xyXG4gICAgICAgIHJldHVybiAoX2EgPSBvYnNlcnZlcnMuZ2V0KHRoaXMpKVttZXRob2RdLmFwcGx5KF9hLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxufSk7XG5cbnZhciBpbmRleCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAvLyBFeHBvcnQgZXhpc3RpbmcgaW1wbGVtZW50YXRpb24gaWYgYXZhaWxhYmxlLlxyXG4gICAgaWYgKHR5cGVvZiBnbG9iYWwkMS5SZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICByZXR1cm4gZ2xvYmFsJDEuUmVzaXplT2JzZXJ2ZXI7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gUmVzaXplT2JzZXJ2ZXI7XHJcbn0pKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGluZGV4O1xuIiwiaW1wb3J0IFJlc2l6ZU9ic2VydmVyIGZyb20gJ3Jlc2l6ZS1vYnNlcnZlci1wb2x5ZmlsbCc7XG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IENvbnN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbnZhciBlbGVtZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuZnVuY3Rpb24gb25SZXNpemUoZW50aXRpZXMpIHtcbiAgZW50aXRpZXMuZm9yRWFjaChmdW5jdGlvbiAoZW50aXR5KSB7XG4gICAgdmFyIF9lbGVtZW50TGlzdGVuZXJzJGdldDtcbiAgICB2YXIgdGFyZ2V0ID0gZW50aXR5LnRhcmdldDtcbiAgICAoX2VsZW1lbnRMaXN0ZW5lcnMkZ2V0ID0gZWxlbWVudExpc3RlbmVycy5nZXQodGFyZ2V0KSkgPT09IG51bGwgfHwgX2VsZW1lbnRMaXN0ZW5lcnMkZ2V0ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZWxlbWVudExpc3RlbmVycyRnZXQuZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBsaXN0ZW5lcih0YXJnZXQpO1xuICAgIH0pO1xuICB9KTtcbn1cbi8vIE5vdGU6IFJlc2l6ZU9ic2VydmVyIHBvbHlmaWxsIG5vdCBzdXBwb3J0IG9wdGlvbiB0byBtZWFzdXJlIGJvcmRlci1ib3ggcmVzaXplXG52YXIgcmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIob25SZXNpemUpO1xuLy8gRGV2IGVudiBvbmx5XG5leHBvcnQgdmFyIF9lbCA9IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBlbGVtZW50TGlzdGVuZXJzIDogbnVsbDsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuZXhwb3J0IHZhciBfcnMgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gb25SZXNpemUgOiBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gT2JzZXJ2ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbmV4cG9ydCBmdW5jdGlvbiBvYnNlcnZlKGVsZW1lbnQsIGNhbGxiYWNrKSB7XG4gIGlmICghZWxlbWVudExpc3RlbmVycy5oYXMoZWxlbWVudCkpIHtcbiAgICBlbGVtZW50TGlzdGVuZXJzLnNldChlbGVtZW50LCBuZXcgU2V0KCkpO1xuICAgIHJlc2l6ZU9ic2VydmVyLm9ic2VydmUoZWxlbWVudCk7XG4gIH1cbiAgZWxlbWVudExpc3RlbmVycy5nZXQoZWxlbWVudCkuYWRkKGNhbGxiYWNrKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1bm9ic2VydmUoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgaWYgKGVsZW1lbnRMaXN0ZW5lcnMuaGFzKGVsZW1lbnQpKSB7XG4gICAgZWxlbWVudExpc3RlbmVycy5nZXQoZWxlbWVudCkuZGVsZXRlKGNhbGxiYWNrKTtcbiAgICBpZiAoIWVsZW1lbnRMaXN0ZW5lcnMuZ2V0KGVsZW1lbnQpLnNpemUpIHtcbiAgICAgIHJlc2l6ZU9ic2VydmVyLnVub2JzZXJ2ZShlbGVtZW50KTtcbiAgICAgIGVsZW1lbnRMaXN0ZW5lcnMuZGVsZXRlKGVsZW1lbnQpO1xuICAgIH1cbiAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHtcbiAgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpO1xuICB9XG59IiwiaW1wb3J0IHRvUHJvcGVydHlLZXkgZnJvbSBcIi4vdG9Qcm9wZXJ0eUtleS5qc1wiO1xuZnVuY3Rpb24gX2RlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTtcbiAgICBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7XG4gICAgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlO1xuICAgIGlmIChcInZhbHVlXCIgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgdG9Qcm9wZXJ0eUtleShkZXNjcmlwdG9yLmtleSksIGRlc2NyaXB0b3IpO1xuICB9XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb25zdHJ1Y3RvciwgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgcmV0dXJuIENvbnN0cnVjdG9yO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7XG4gIF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZi5iaW5kKCkgOiBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICAgIG8uX19wcm90b19fID0gcDtcbiAgICByZXR1cm4gbztcbiAgfTtcbiAgcmV0dXJuIF9zZXRQcm90b3R5cGVPZihvLCBwKTtcbn0iLCJpbXBvcnQgc2V0UHJvdG90eXBlT2YgZnJvbSBcIi4vc2V0UHJvdG90eXBlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykge1xuICBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09IFwiZnVuY3Rpb25cIiAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICB9XG4gIHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogc3ViQ2xhc3MsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShzdWJDbGFzcywgXCJwcm90b3R5cGVcIiwge1xuICAgIHdyaXRhYmxlOiBmYWxzZVxuICB9KTtcbiAgaWYgKHN1cGVyQ2xhc3MpIHNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICBfZ2V0UHJvdG90eXBlT2YgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3QuZ2V0UHJvdG90eXBlT2YuYmluZCgpIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgICByZXR1cm4gby5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKG8pO1xuICB9O1xuICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKSB7XG4gIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJ1bmRlZmluZWRcIiB8fCAhUmVmbGVjdC5jb25zdHJ1Y3QpIHJldHVybiBmYWxzZTtcbiAgaWYgKFJlZmxlY3QuY29uc3RydWN0LnNoYW0pIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiBQcm94eSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gdHJ1ZTtcbiAgdHJ5IHtcbiAgICBCb29sZWFuLnByb3RvdHlwZS52YWx1ZU9mLmNhbGwoUmVmbGVjdC5jb25zdHJ1Y3QoQm9vbGVhbiwgW10sIGZ1bmN0aW9uICgpIHt9KSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgaWYgKHNlbGYgPT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtcbiAgfVxuICByZXR1cm4gc2VsZjtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiLi90eXBlb2YuanNcIjtcbmltcG9ydCBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIi4vYXNzZXJ0VGhpc0luaXRpYWxpemVkLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybihzZWxmLCBjYWxsKSB7XG4gIGlmIChjYWxsICYmIChfdHlwZW9mKGNhbGwpID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBjYWxsID09PSBcImZ1bmN0aW9uXCIpKSB7XG4gICAgcmV0dXJuIGNhbGw7XG4gIH0gZWxzZSBpZiAoY2FsbCAhPT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkRlcml2ZWQgY29uc3RydWN0b3JzIG1heSBvbmx5IHJldHVybiBvYmplY3Qgb3IgdW5kZWZpbmVkXCIpO1xuICB9XG4gIHJldHVybiBhc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZik7XG59IiwiaW1wb3J0IGdldFByb3RvdHlwZU9mIGZyb20gXCIuL2dldFByb3RvdHlwZU9mLmpzXCI7XG5pbXBvcnQgaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0IGZyb20gXCIuL2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdC5qc1wiO1xuaW1wb3J0IHBvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4gZnJvbSBcIi4vcG9zc2libGVDb25zdHJ1Y3RvclJldHVybi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2NyZWF0ZVN1cGVyKERlcml2ZWQpIHtcbiAgdmFyIGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgPSBpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIF9jcmVhdGVTdXBlckludGVybmFsKCkge1xuICAgIHZhciBTdXBlciA9IGdldFByb3RvdHlwZU9mKERlcml2ZWQpLFxuICAgICAgcmVzdWx0O1xuICAgIGlmIChoYXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0KSB7XG4gICAgICB2YXIgTmV3VGFyZ2V0ID0gZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3I7XG4gICAgICByZXN1bHQgPSBSZWZsZWN0LmNvbnN0cnVjdChTdXBlciwgYXJndW1lbnRzLCBOZXdUYXJnZXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgPSBTdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cbiAgICByZXR1cm4gcG9zc2libGVDb25zdHJ1Y3RvclJldHVybih0aGlzLCByZXN1bHQpO1xuICB9O1xufSIsImltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfY3JlYXRlU3VwZXIgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZVN1cGVyXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG4vKipcbiAqIEZhbGxiYWNrIHRvIGZpbmRET01Ob2RlIGlmIG9yaWdpbiByZWYgZG8gbm90IHByb3ZpZGUgYW55IGRvbSBlbGVtZW50XG4gKi9cbnZhciBEb21XcmFwcGVyID0gLyojX19QVVJFX18qL2Z1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhEb21XcmFwcGVyLCBfUmVhY3QkQ29tcG9uZW50KTtcbiAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihEb21XcmFwcGVyKTtcbiAgZnVuY3Rpb24gRG9tV3JhcHBlcigpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRG9tV3JhcHBlcik7XG4gICAgcmV0dXJuIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG4gIF9jcmVhdGVDbGFzcyhEb21XcmFwcGVyLCBbe1xuICAgIGtleTogXCJyZW5kZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgcmV0dXJuIHRoaXMucHJvcHMuY2hpbGRyZW47XG4gICAgfVxuICB9XSk7XG4gIHJldHVybiBEb21XcmFwcGVyO1xufShSZWFjdC5Db21wb25lbnQpO1xuZXhwb3J0IHsgRG9tV3JhcHBlciBhcyBkZWZhdWx0IH07IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IHZhciBDb2xsZWN0aW9uQ29udGV4dCA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVDb250ZXh0KG51bGwpO1xuLyoqXG4gKiBDb2xsZWN0IGFsbCB0aGUgcmVzaXplIGV2ZW50IGZyb20gY2hpbGRyZW4gUmVzaXplT2JzZXJ2ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIENvbGxlY3Rpb24oX3JlZikge1xuICB2YXIgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgIG9uQmF0Y2hSZXNpemUgPSBfcmVmLm9uQmF0Y2hSZXNpemU7XG4gIHZhciByZXNpemVJZFJlZiA9IFJlYWN0LnVzZVJlZigwKTtcbiAgdmFyIHJlc2l6ZUluZm9zUmVmID0gUmVhY3QudXNlUmVmKFtdKTtcbiAgdmFyIG9uQ29sbGVjdGlvblJlc2l6ZSA9IFJlYWN0LnVzZUNvbnRleHQoQ29sbGVjdGlvbkNvbnRleHQpO1xuICB2YXIgb25SZXNpemUgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAoc2l6ZSwgZWxlbWVudCwgZGF0YSkge1xuICAgIHJlc2l6ZUlkUmVmLmN1cnJlbnQgKz0gMTtcbiAgICB2YXIgY3VycmVudElkID0gcmVzaXplSWRSZWYuY3VycmVudDtcbiAgICByZXNpemVJbmZvc1JlZi5jdXJyZW50LnB1c2goe1xuICAgICAgc2l6ZTogc2l6ZSxcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBkYXRhOiBkYXRhXG4gICAgfSk7XG4gICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoY3VycmVudElkID09PSByZXNpemVJZFJlZi5jdXJyZW50KSB7XG4gICAgICAgIG9uQmF0Y2hSZXNpemUgPT09IG51bGwgfHwgb25CYXRjaFJlc2l6ZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25CYXRjaFJlc2l6ZShyZXNpemVJbmZvc1JlZi5jdXJyZW50KTtcbiAgICAgICAgcmVzaXplSW5mb3NSZWYuY3VycmVudCA9IFtdO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIENvbnRpbnVlIGJ1YmJsaW5nIGlmIHBhcmVudCBleGlzdFxuICAgIG9uQ29sbGVjdGlvblJlc2l6ZSA9PT0gbnVsbCB8fCBvbkNvbGxlY3Rpb25SZXNpemUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uQ29sbGVjdGlvblJlc2l6ZShzaXplLCBlbGVtZW50LCBkYXRhKTtcbiAgfSwgW29uQmF0Y2hSZXNpemUsIG9uQ29sbGVjdGlvblJlc2l6ZV0pO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoQ29sbGVjdGlvbkNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogb25SZXNpemVcbiAgfSwgY2hpbGRyZW4pO1xufSIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgeyBjb21wb3NlUmVmLCBzdXBwb3J0UmVmIH0gZnJvbSBcInJjLXV0aWwvZXMvcmVmXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgZmluZERPTU5vZGUgZnJvbSBcInJjLXV0aWwvZXMvRG9tL2ZpbmRET01Ob2RlXCI7XG5pbXBvcnQgeyBvYnNlcnZlLCB1bm9ic2VydmUgfSBmcm9tICcuLi91dGlscy9vYnNlcnZlclV0aWwnO1xuaW1wb3J0IERvbVdyYXBwZXIgZnJvbSAnLi9Eb21XcmFwcGVyJztcbmltcG9ydCB7IENvbGxlY3Rpb25Db250ZXh0IH0gZnJvbSAnLi4vQ29sbGVjdGlvbic7XG5mdW5jdGlvbiBTaW5nbGVPYnNlcnZlcihwcm9wcywgcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgIGRpc2FibGVkID0gcHJvcHMuZGlzYWJsZWQ7XG4gIHZhciBlbGVtZW50UmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICB2YXIgd3JhcHBlclJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgdmFyIG9uQ29sbGVjdGlvblJlc2l6ZSA9IFJlYWN0LnVzZUNvbnRleHQoQ29sbGVjdGlvbkNvbnRleHQpO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ2hpbGRyZW4gPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBpc1JlbmRlclByb3BzID0gdHlwZW9mIGNoaWxkcmVuID09PSAnZnVuY3Rpb24nO1xuICB2YXIgbWVyZ2VkQ2hpbGRyZW4gPSBpc1JlbmRlclByb3BzID8gY2hpbGRyZW4oZWxlbWVudFJlZikgOiBjaGlsZHJlbjtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU2l6ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgc2l6ZVJlZiA9IFJlYWN0LnVzZVJlZih7XG4gICAgd2lkdGg6IC0xLFxuICAgIGhlaWdodDogLTEsXG4gICAgb2Zmc2V0V2lkdGg6IC0xLFxuICAgIG9mZnNldEhlaWdodDogLTFcbiAgfSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFJlZiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGNhblJlZiA9ICFpc1JlbmRlclByb3BzICYmIC8qI19fUFVSRV9fKi9SZWFjdC5pc1ZhbGlkRWxlbWVudChtZXJnZWRDaGlsZHJlbikgJiYgc3VwcG9ydFJlZihtZXJnZWRDaGlsZHJlbik7XG4gIHZhciBvcmlnaW5SZWYgPSBjYW5SZWYgPyBtZXJnZWRDaGlsZHJlbi5yZWYgOiBudWxsO1xuICB2YXIgbWVyZ2VkUmVmID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGNvbXBvc2VSZWYob3JpZ2luUmVmLCBlbGVtZW50UmVmKTtcbiAgfSwgW29yaWdpblJlZiwgZWxlbWVudFJlZl0pO1xuICB2YXIgZ2V0RG9tID0gZnVuY3Rpb24gZ2V0RG9tKCkge1xuICAgIHJldHVybiBmaW5kRE9NTm9kZShlbGVtZW50UmVmLmN1cnJlbnQpIHx8IGZpbmRET01Ob2RlKHdyYXBwZXJSZWYuY3VycmVudCk7XG4gIH07XG4gIFJlYWN0LnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGdldERvbSgpO1xuICB9KTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IE9ic2VydmUgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgcHJvcHNSZWYgPSBSZWFjdC51c2VSZWYocHJvcHMpO1xuICBwcm9wc1JlZi5jdXJyZW50ID0gcHJvcHM7XG4gIC8vIEhhbmRsZXJcbiAgdmFyIG9uSW50ZXJuYWxSZXNpemUgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAodGFyZ2V0KSB7XG4gICAgdmFyIF9wcm9wc1JlZiRjdXJyZW50ID0gcHJvcHNSZWYuY3VycmVudCxcbiAgICAgIG9uUmVzaXplID0gX3Byb3BzUmVmJGN1cnJlbnQub25SZXNpemUsXG4gICAgICBkYXRhID0gX3Byb3BzUmVmJGN1cnJlbnQuZGF0YTtcbiAgICB2YXIgX3RhcmdldCRnZXRCb3VuZGluZ0NsID0gdGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgd2lkdGggPSBfdGFyZ2V0JGdldEJvdW5kaW5nQ2wud2lkdGgsXG4gICAgICBoZWlnaHQgPSBfdGFyZ2V0JGdldEJvdW5kaW5nQ2wuaGVpZ2h0O1xuICAgIHZhciBvZmZzZXRXaWR0aCA9IHRhcmdldC5vZmZzZXRXaWR0aCxcbiAgICAgIG9mZnNldEhlaWdodCA9IHRhcmdldC5vZmZzZXRIZWlnaHQ7XG4gICAgLyoqXG4gICAgICogUmVzaXplIG9ic2VydmVyIHRyaWdnZXIgd2hlbiBjb250ZW50IHNpemUgY2hhbmdlZC5cbiAgICAgKiBJbiBtb3N0IGNhc2Ugd2UganVzdCBjYXJlIGFib3V0IGVsZW1lbnQgc2l6ZSxcbiAgICAgKiBsZXQncyB1c2UgYGJvdW5kYXJ5YCBpbnN0ZWFkIG9mIGBjb250ZW50UmVjdGAgaGVyZSB0byBhdm9pZCBzaGFraW5nLlxuICAgICAqL1xuICAgIHZhciBmaXhlZFdpZHRoID0gTWF0aC5mbG9vcih3aWR0aCk7XG4gICAgdmFyIGZpeGVkSGVpZ2h0ID0gTWF0aC5mbG9vcihoZWlnaHQpO1xuICAgIGlmIChzaXplUmVmLmN1cnJlbnQud2lkdGggIT09IGZpeGVkV2lkdGggfHwgc2l6ZVJlZi5jdXJyZW50LmhlaWdodCAhPT0gZml4ZWRIZWlnaHQgfHwgc2l6ZVJlZi5jdXJyZW50Lm9mZnNldFdpZHRoICE9PSBvZmZzZXRXaWR0aCB8fCBzaXplUmVmLmN1cnJlbnQub2Zmc2V0SGVpZ2h0ICE9PSBvZmZzZXRIZWlnaHQpIHtcbiAgICAgIHZhciBzaXplID0ge1xuICAgICAgICB3aWR0aDogZml4ZWRXaWR0aCxcbiAgICAgICAgaGVpZ2h0OiBmaXhlZEhlaWdodCxcbiAgICAgICAgb2Zmc2V0V2lkdGg6IG9mZnNldFdpZHRoLFxuICAgICAgICBvZmZzZXRIZWlnaHQ6IG9mZnNldEhlaWdodFxuICAgICAgfTtcbiAgICAgIHNpemVSZWYuY3VycmVudCA9IHNpemU7XG4gICAgICAvLyBJRSBpcyBzdHJhbmdlLCByaWdodD9cbiAgICAgIHZhciBtZXJnZWRPZmZzZXRXaWR0aCA9IG9mZnNldFdpZHRoID09PSBNYXRoLnJvdW5kKHdpZHRoKSA/IHdpZHRoIDogb2Zmc2V0V2lkdGg7XG4gICAgICB2YXIgbWVyZ2VkT2Zmc2V0SGVpZ2h0ID0gb2Zmc2V0SGVpZ2h0ID09PSBNYXRoLnJvdW5kKGhlaWdodCkgPyBoZWlnaHQgOiBvZmZzZXRIZWlnaHQ7XG4gICAgICB2YXIgc2l6ZUluZm8gPSBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIHNpemUpLCB7fSwge1xuICAgICAgICBvZmZzZXRXaWR0aDogbWVyZ2VkT2Zmc2V0V2lkdGgsXG4gICAgICAgIG9mZnNldEhlaWdodDogbWVyZ2VkT2Zmc2V0SGVpZ2h0XG4gICAgICB9KTtcbiAgICAgIC8vIExldCBjb2xsZWN0aW9uIGtub3cgd2hhdCBoYXBwZW5lZFxuICAgICAgb25Db2xsZWN0aW9uUmVzaXplID09PSBudWxsIHx8IG9uQ29sbGVjdGlvblJlc2l6ZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25Db2xsZWN0aW9uUmVzaXplKHNpemVJbmZvLCB0YXJnZXQsIGRhdGEpO1xuICAgICAgaWYgKG9uUmVzaXplKSB7XG4gICAgICAgIC8vIGRlZmVyIHRoZSBjYWxsYmFjayBidXQgbm90IGRlZmVyIHRvIG5leHQgZnJhbWVcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgb25SZXNpemUoc2l6ZUluZm8sIHRhcmdldCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSwgW10pO1xuICAvLyBEeW5hbWljIG9ic2VydmVcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY3VycmVudEVsZW1lbnQgPSBnZXREb20oKTtcbiAgICBpZiAoY3VycmVudEVsZW1lbnQgJiYgIWRpc2FibGVkKSB7XG4gICAgICBvYnNlcnZlKGN1cnJlbnRFbGVtZW50LCBvbkludGVybmFsUmVzaXplKTtcbiAgICB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB1bm9ic2VydmUoY3VycmVudEVsZW1lbnQsIG9uSW50ZXJuYWxSZXNpemUpO1xuICAgIH07XG4gIH0sIFtlbGVtZW50UmVmLmN1cnJlbnQsIGRpc2FibGVkXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KERvbVdyYXBwZXIsIHtcbiAgICByZWY6IHdyYXBwZXJSZWZcbiAgfSwgY2FuUmVmID8gLyojX19QVVJFX18qL1JlYWN0LmNsb25lRWxlbWVudChtZXJnZWRDaGlsZHJlbiwge1xuICAgIHJlZjogbWVyZ2VkUmVmXG4gIH0pIDogbWVyZ2VkQ2hpbGRyZW4pO1xufVxudmFyIFJlZlNpbmdsZU9ic2VydmVyID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoU2luZ2xlT2JzZXJ2ZXIpO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgUmVmU2luZ2xlT2JzZXJ2ZXIuZGlzcGxheU5hbWUgPSAnU2luZ2xlT2JzZXJ2ZXInO1xufVxuZXhwb3J0IGRlZmF1bHQgUmVmU2luZ2xlT2JzZXJ2ZXI7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgdG9BcnJheSBmcm9tIFwicmMtdXRpbC9lcy9DaGlsZHJlbi90b0FycmF5XCI7XG5pbXBvcnQgeyB3YXJuaW5nIH0gZnJvbSBcInJjLXV0aWwvZXMvd2FybmluZ1wiO1xuaW1wb3J0IFNpbmdsZU9ic2VydmVyIGZyb20gJy4vU2luZ2xlT2JzZXJ2ZXInO1xuaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4vQ29sbGVjdGlvbic7XG52YXIgSU5URVJOQUxfUFJFRklYX0tFWSA9ICdyYy1vYnNlcnZlci1rZXknO1xuaW1wb3J0IHsgX3JzIH0gZnJvbSAnLi91dGlscy9vYnNlcnZlclV0aWwnO1xuZXhwb3J0IHsgLyoqIEBwcml2YXRlIFRlc3Qgb25seSBmb3IgbW9jayB0cmlnZ2VyIHJlc2l6ZSBldmVudCAqL1xuX3JzIH07XG5mdW5jdGlvbiBSZXNpemVPYnNlcnZlcihwcm9wcywgcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuO1xuICB2YXIgY2hpbGROb2RlcyA9IHR5cGVvZiBjaGlsZHJlbiA9PT0gJ2Z1bmN0aW9uJyA/IFtjaGlsZHJlbl0gOiB0b0FycmF5KGNoaWxkcmVuKTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBpZiAoY2hpbGROb2Rlcy5sZW5ndGggPiAxKSB7XG4gICAgICB3YXJuaW5nKGZhbHNlLCAnRmluZCBtb3JlIHRoYW4gb25lIGNoaWxkIG5vZGUgd2l0aCBgY2hpbGRyZW5gIGluIFJlc2l6ZU9ic2VydmVyLiBQbGVhc2UgdXNlIFJlc2l6ZU9ic2VydmVyLkNvbGxlY3Rpb24gaW5zdGVhZC4nKTtcbiAgICB9IGVsc2UgaWYgKGNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB3YXJuaW5nKGZhbHNlLCAnYGNoaWxkcmVuYCBvZiBSZXNpemVPYnNlcnZlciBpcyBlbXB0eS4gTm90aGluZyBpcyBpbiBvYnNlcnZlLicpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY2hpbGROb2Rlcy5tYXAoZnVuY3Rpb24gKGNoaWxkLCBpbmRleCkge1xuICAgIHZhciBrZXkgPSAoY2hpbGQgPT09IG51bGwgfHwgY2hpbGQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGNoaWxkLmtleSkgfHwgXCJcIi5jb25jYXQoSU5URVJOQUxfUFJFRklYX0tFWSwgXCItXCIpLmNvbmNhdChpbmRleCk7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFNpbmdsZU9ic2VydmVyLCBfZXh0ZW5kcyh7fSwgcHJvcHMsIHtcbiAgICAgIGtleToga2V5LFxuICAgICAgcmVmOiBpbmRleCA9PT0gMCA/IHJlZiA6IHVuZGVmaW5lZFxuICAgIH0pLCBjaGlsZCk7XG4gIH0pO1xufVxudmFyIFJlZlJlc2l6ZU9ic2VydmVyID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoUmVzaXplT2JzZXJ2ZXIpO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgUmVmUmVzaXplT2JzZXJ2ZXIuZGlzcGxheU5hbWUgPSAnUmVzaXplT2JzZXJ2ZXInO1xufVxuUmVmUmVzaXplT2JzZXJ2ZXIuQ29sbGVjdGlvbiA9IENvbGxlY3Rpb247XG5leHBvcnQgZGVmYXVsdCBSZWZSZXNpemVPYnNlcnZlcjsiLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5mdW5jdGlvbiBnZXRVc2VJZCgpIHtcbiAgLy8gV2UgbmVlZCBmdWxseSBjbG9uZSBSZWFjdCBmdW5jdGlvbiBoZXJlIHRvIGF2b2lkIHdlYnBhY2sgd2FybmluZyBSZWFjdCAxNyBkbyBub3QgZXhwb3J0IGB1c2VJZGBcbiAgdmFyIGZ1bGxDbG9uZSA9IF9vYmplY3RTcHJlYWQoe30sIFJlYWN0KTtcbiAgcmV0dXJuIGZ1bGxDbG9uZS51c2VJZDtcbn1cbnZhciB1dWlkID0gMDtcblxuLyoqIEBwcml2YXRlIE5vdGUgb25seSB3b3JrZWQgaW4gZGV2ZWxvcCBlbnYuIE5vdCB3b3JrIGluIHByb2R1Y3Rpb24uICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRVdWlkKCkge1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIHV1aWQgPSAwO1xuICB9XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VJZChpZCkge1xuICAvLyBJbm5lciBpZCBmb3IgYWNjZXNzaWJpbGl0eSB1c2FnZS4gT25seSB3b3JrIGluIGNsaWVudCBzaWRlXG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZSgnc3NyLWlkJyksXG4gICAgX1JlYWN0JHVzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZSwgMiksXG4gICAgaW5uZXJJZCA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgc2V0SW5uZXJJZCA9IF9SZWFjdCR1c2VTdGF0ZTJbMV07XG4gIHZhciB1c2VPcmlnaW5JZCA9IGdldFVzZUlkKCk7XG4gIHZhciByZWFjdE5hdGl2ZUlkID0gdXNlT3JpZ2luSWQgPT09IG51bGwgfHwgdXNlT3JpZ2luSWQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHVzZU9yaWdpbklkKCk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCF1c2VPcmlnaW5JZCkge1xuICAgICAgdmFyIG5leHRJZCA9IHV1aWQ7XG4gICAgICB1dWlkICs9IDE7XG4gICAgICBzZXRJbm5lcklkKFwicmNfdW5pcXVlX1wiLmNvbmNhdChuZXh0SWQpKTtcbiAgICB9XG4gIH0sIFtdKTtcblxuICAvLyBEZXZlbG9wZXIgcGFzc2VkIGlkIGlzIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGhcbiAgaWYgKGlkKSB7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgLy8gVGVzdCBlbnYgYWx3YXlzIHJldHVybiBtb2NrIGlkXG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnKSB7XG4gICAgcmV0dXJuICd0ZXN0LWlkJztcbiAgfVxuXG4gIC8vIFJldHVybiByZWFjdCBuYXRpdmUgaWQgb3IgaW5uZXIgaWRcbiAgcmV0dXJuIHJlYWN0TmF0aXZlSWQgfHwgaW5uZXJJZDtcbn0iLCJleHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIGFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCBuYXZpZ2F0b3IudmVuZG9yIHx8IHdpbmRvdy5vcGVyYTtcbiAgcmV0dXJuIC8oYW5kcm9pZHxiYlxcZCt8bWVlZ28pLittb2JpbGV8YXZhbnRnb3xiYWRhXFwvfGJsYWNrYmVycnl8YmxhemVyfGNvbXBhbHxlbGFpbmV8ZmVubmVjfGhpcHRvcHxpZW1vYmlsZXxpcChob25lfG9kKXxpcmlzfGtpbmRsZXxsZ2UgfG1hZW1vfG1pZHB8bW1wfG1vYmlsZS4rZmlyZWZveHxuZXRmcm9udHxvcGVyYSBtKG9ifGluKWl8cGFsbSggb3MpP3xwaG9uZXxwKGl4aXxyZSlcXC98cGx1Y2tlcnxwb2NrZXR8cHNwfHNlcmllcyg0fDYpMHxzeW1iaWFufHRyZW98dXBcXC4oYnJvd3NlcnxsaW5rKXx2b2RhZm9uZXx3YXB8d2luZG93cyBjZXx4ZGF8eGlpbm98YW5kcm9pZHxpcGFkfHBsYXlib29rfHNpbGsvaS50ZXN0KGFnZW50KSB8fCAvMTIwN3w2MzEwfDY1OTB8M2dzb3w0dGhwfDUwWzEtNl1pfDc3MHN8ODAyc3xhIHdhfGFiYWN8YWMoZXJ8b298cy0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8LW18ciB8cyApfGF2YW58YmUoY2t8bGx8bnEpfGJpKGxifHJkKXxibChhY3xheil8YnIoZXx2KXd8YnVtYnxidy0obnx1KXxjNTVcXC98Y2FwaXxjY3dhfGNkbS18Y2VsbHxjaHRtfGNsZGN8Y21kLXxjbyhtcHxuZCl8Y3Jhd3xkYShpdHxsbHxuZyl8ZGJ0ZXxkYy1zfGRldml8ZGljYXxkbW9ifGRvKGN8cClvfGRzKDEyfC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoLXxfKXxnMSB1fGc1NjB8Z2VuZXxnZi01fGctbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZC0obXxwfHQpfGhlaS18aGkocHR8dGEpfGhwKCBpfGlwKXxocy1jfGh0KGMoLXwgfF98YXxnfHB8c3x0KXx0cCl8aHUoYXd8dGMpfGktKDIwfGdvfG1hKXxpMjMwfGlhYyggfC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Yy18a3lvKGN8ayl8bGUobm98eGkpfGxnKCBnfFxcLyhrfGx8dSl8NTB8NTR8LVthLXddKXxsaWJ3fGx5bnh8bTEtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG0tY3J8bWUocmN8cmkpfG1pKG84fG9hfHRzKXxtbWVmfG1vKDAxfDAyfGJpfGRlfGRvfHQoLXwgfG98dil8enopfG10KDUwfHAxfHYgKXxtd2JwfG15d2F8bjEwWzAtMl18bjIwWzItM118bjMwKDB8Mil8bjUwKDB8Mnw1KXxuNygwKDB8MSl8MTApfG5lKChjfG0pLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8LShbMS04XXxjKSl8cGhpbHxwaXJlfHBsKGF5fHVjKXxwbi0yfHBvKGNrfHJ0fHNlKXxwcm94fHBzaW98cHQtZ3xxYS1hfHFjKDA3fDEyfDIxfDMyfDYwfC1bMi03XXxpLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGgtfG9vfHAtKXxzZGtcXC98c2UoYygtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaC18c2hhcnxzaWUoLXxtKXxzay0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGgtfHYtfHYgKXxzeSgwMXxtYil8dDIoMTh8NTApfHQ2KDAwfDEwfDE4KXx0YShndHxsayl8dGNsLXx0ZGctfHRlbChpfG0pfHRpbS18dC1tb3x0byhwbHxzaCl8dHMoNzB8bS18bTN8bTUpfHR4LTl8dXAoXFwuYnxnMXxzaSl8dXRzdHx2NDAwfHY3NTB8dmVyaXx2aShyZ3x0ZSl8dmsoNDB8NVswLTNdfC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKC18ICl8d2ViY3x3aGl0fHdpKGcgfG5jfG53KXx3bWxifHdvbnV8eDcwMHx5YXMtfHlvdXJ8emV0b3x6dGUtL2kudGVzdChhZ2VudCA9PT0gbnVsbCB8fCBhZ2VudCA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWdlbnQuc3Vic3RyKDAsIDQpKTtcbn0pOyIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbnZhciBUcmlnZ2VyQ29udGV4dCA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVDb250ZXh0KG51bGwpO1xuZXhwb3J0IGRlZmF1bHQgVHJpZ2dlckNvbnRleHQ7IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZnVuY3Rpb24gdG9BcnJheSh2YWwpIHtcbiAgcmV0dXJuIHZhbCA/IEFycmF5LmlzQXJyYXkodmFsKSA/IHZhbCA6IFt2YWxdIDogW107XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VBY3Rpb24obW9iaWxlLCBhY3Rpb24sIHNob3dBY3Rpb24sIGhpZGVBY3Rpb24pIHtcbiAgcmV0dXJuIFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHZhciBtZXJnZWRTaG93QWN0aW9uID0gdG9BcnJheShzaG93QWN0aW9uICE9PSBudWxsICYmIHNob3dBY3Rpb24gIT09IHZvaWQgMCA/IHNob3dBY3Rpb24gOiBhY3Rpb24pO1xuICAgIHZhciBtZXJnZWRIaWRlQWN0aW9uID0gdG9BcnJheShoaWRlQWN0aW9uICE9PSBudWxsICYmIGhpZGVBY3Rpb24gIT09IHZvaWQgMCA/IGhpZGVBY3Rpb24gOiBhY3Rpb24pO1xuICAgIHZhciBzaG93QWN0aW9uU2V0ID0gbmV3IFNldChtZXJnZWRTaG93QWN0aW9uKTtcbiAgICB2YXIgaGlkZUFjdGlvblNldCA9IG5ldyBTZXQobWVyZ2VkSGlkZUFjdGlvbik7XG4gICAgaWYgKG1vYmlsZSkge1xuICAgICAgaWYgKHNob3dBY3Rpb25TZXQuaGFzKCdob3ZlcicpKSB7XG4gICAgICAgIHNob3dBY3Rpb25TZXQuZGVsZXRlKCdob3ZlcicpO1xuICAgICAgICBzaG93QWN0aW9uU2V0LmFkZCgnY2xpY2snKTtcbiAgICAgIH1cbiAgICAgIGlmIChoaWRlQWN0aW9uU2V0LmhhcygnaG92ZXInKSkge1xuICAgICAgICBoaWRlQWN0aW9uU2V0LmRlbGV0ZSgnaG92ZXInKTtcbiAgICAgICAgaGlkZUFjdGlvblNldC5hZGQoJ2NsaWNrJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbc2hvd0FjdGlvblNldCwgaGlkZUFjdGlvblNldF07XG4gIH0sIFttb2JpbGUsIGFjdGlvbiwgc2hvd0FjdGlvbiwgaGlkZUFjdGlvbl0pO1xufSIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoZWxlbWVudCkge1xuICBpZiAoIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQub2Zmc2V0UGFyZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGVsZW1lbnQuZ2V0QkJveCkge1xuICAgICAgdmFyIF9nZXRCQm94ID0gZWxlbWVudC5nZXRCQm94KCksXG4gICAgICAgIHdpZHRoID0gX2dldEJCb3gud2lkdGgsXG4gICAgICAgIGhlaWdodCA9IF9nZXRCQm94LmhlaWdodDtcbiAgICAgIGlmICh3aWR0aCB8fCBoZWlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCkge1xuICAgICAgdmFyIF9lbGVtZW50JGdldEJvdW5kaW5nQyA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICAgIF93aWR0aCA9IF9lbGVtZW50JGdldEJvdW5kaW5nQy53aWR0aCxcbiAgICAgICAgX2hlaWdodCA9IF9lbGVtZW50JGdldEJvdW5kaW5nQy5oZWlnaHQ7XG4gICAgICBpZiAoX3dpZHRoIHx8IF9oZWlnaHQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn0pOyIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5mdW5jdGlvbiBpc1BvaW50c0VxKCkge1xuICB2YXIgYTEgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFtdO1xuICB2YXIgYTIgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IFtdO1xuICB2YXIgaXNBbGlnblBvaW50ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiB1bmRlZmluZWQ7XG4gIGlmIChpc0FsaWduUG9pbnQpIHtcbiAgICByZXR1cm4gYTFbMF0gPT09IGEyWzBdO1xuICB9XG4gIHJldHVybiBhMVswXSA9PT0gYTJbMF0gJiYgYTFbMV0gPT09IGEyWzFdO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldEFsaWduUG9wdXBDbGFzc05hbWUoYnVpbHRpblBsYWNlbWVudHMsIHByZWZpeENscywgYWxpZ24sIGlzQWxpZ25Qb2ludCkge1xuICB2YXIgcG9pbnRzID0gYWxpZ24ucG9pbnRzO1xuICB2YXIgcGxhY2VtZW50cyA9IE9iamVjdC5rZXlzKGJ1aWx0aW5QbGFjZW1lbnRzKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwbGFjZW1lbnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgdmFyIF9idWlsdGluUGxhY2VtZW50cyRwbDtcbiAgICB2YXIgcGxhY2VtZW50ID0gcGxhY2VtZW50c1tpXTtcbiAgICBpZiAoaXNQb2ludHNFcSgoX2J1aWx0aW5QbGFjZW1lbnRzJHBsID0gYnVpbHRpblBsYWNlbWVudHNbcGxhY2VtZW50XSkgPT09IG51bGwgfHwgX2J1aWx0aW5QbGFjZW1lbnRzJHBsID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYnVpbHRpblBsYWNlbWVudHMkcGwucG9pbnRzLCBwb2ludHMsIGlzQWxpZ25Qb2ludCkpIHtcbiAgICAgIHJldHVybiBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXBsYWNlbWVudC1cIikuY29uY2F0KHBsYWNlbWVudCk7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn1cblxuLyoqIEBkZXByZWNhdGVkIFdlIHNob3VsZCBub3QgdXNlIHRoaXMgaWYgd2UgY2FuIHJlZmFjdG9yIGFsbCBkZXBzICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW90aW9uKHByZWZpeENscywgbW90aW9uLCBhbmltYXRpb24sIHRyYW5zaXRpb25OYW1lKSB7XG4gIGlmIChtb3Rpb24pIHtcbiAgICByZXR1cm4gbW90aW9uO1xuICB9XG4gIGlmIChhbmltYXRpb24pIHtcbiAgICByZXR1cm4ge1xuICAgICAgbW90aW9uTmFtZTogXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1cIikuY29uY2F0KGFuaW1hdGlvbilcbiAgICB9O1xuICB9XG4gIGlmICh0cmFuc2l0aW9uTmFtZSkge1xuICAgIHJldHVybiB7XG4gICAgICBtb3Rpb25OYW1lOiB0cmFuc2l0aW9uTmFtZVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0V2luKGVsZSkge1xuICByZXR1cm4gZWxlLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG59XG5cbi8qKlxuICogR2V0IGFsbCB0aGUgc2Nyb2xsYWJsZSBwYXJlbnQgZWxlbWVudHMgb2YgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSBlbGUgICAgICAgVGhlIGVsZW1lbnQgdG8gYmUgZGV0ZWN0ZWRcbiAqIEBwYXJhbSBhcmVhT25seSAgT25seSByZXR1cm4gdGhlIHBhcmVudCB3aGljaCB3aWxsIGN1dCB2aXNpYmxlIGFyZWFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbGxlY3RTY3JvbGxlcihlbGUpIHtcbiAgdmFyIHNjcm9sbGVyTGlzdCA9IFtdO1xuICB2YXIgY3VycmVudCA9IGVsZSA9PT0gbnVsbCB8fCBlbGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGVsZS5wYXJlbnRFbGVtZW50O1xuICB2YXIgc2Nyb2xsU3R5bGUgPSBbJ2hpZGRlbicsICdzY3JvbGwnLCAnY2xpcCcsICdhdXRvJ107XG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgdmFyIF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdCA9IGdldFdpbihjdXJyZW50KS5nZXRDb21wdXRlZFN0eWxlKGN1cnJlbnQpLFxuICAgICAgb3ZlcmZsb3dYID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Lm92ZXJmbG93WCxcbiAgICAgIG92ZXJmbG93WSA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdC5vdmVyZmxvd1ksXG4gICAgICBvdmVyZmxvdyA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdC5vdmVyZmxvdztcbiAgICBpZiAoW292ZXJmbG93WCwgb3ZlcmZsb3dZLCBvdmVyZmxvd10uc29tZShmdW5jdGlvbiAobykge1xuICAgICAgcmV0dXJuIHNjcm9sbFN0eWxlLmluY2x1ZGVzKG8pO1xuICAgIH0pKSB7XG4gICAgICBzY3JvbGxlckxpc3QucHVzaChjdXJyZW50KTtcbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50RWxlbWVudDtcbiAgfVxuICByZXR1cm4gc2Nyb2xsZXJMaXN0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRvTnVtKG51bSkge1xuICB2YXIgZGVmYXVsdFZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAxO1xuICByZXR1cm4gTnVtYmVyLmlzTmFOKG51bSkgPyBkZWZhdWx0VmFsdWUgOiBudW07XG59XG5mdW5jdGlvbiBnZXRQeFZhbHVlKHZhbCkge1xuICByZXR1cm4gdG9OdW0ocGFyc2VGbG9hdCh2YWwpLCAwKTtcbn1cbi8qKlxuICpcbiAqXG4gKiAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqICAqICAgICAgICAgICAgICBCb3JkZXIgICAgICAgICAgICAgICAgKlxuICogICogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAqXG4gKiAgKiAgICAgKiAgICAgICAgICAgICAgICAgICogICAgICogICAgICpcbiAqICAqICBCICAqICAgICAgICAgICAgICAgICAgKiAgUyAgKiAgQiAgKlxuICogICogIG8gICogICAgICAgICAgICAgICAgICAqICBjICAqICBvICAqXG4gKiAgKiAgciAgKiAgICAgIENvbnRlbnQgICAgICogIHIgICogIHIgICpcbiAqICAqICBkICAqICAgICAgICAgICAgICAgICAgKiAgbyAgKiAgZCAgKlxuICogICogIGUgICogICAgICAgICAgICAgICAgICAqICBsICAqICBlICAqXG4gKiAgKiAgciAgKioqKioqKioqKioqKioqKioqKiogIGwgICogIHIgICpcbiAqICAqICAgICAqICAgICAgICBTY3JvbGwgICAgICAgICAgKiAgICAgKlxuICogICogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqICAgICAqXG4gKiAgKiAgICAgICAgICAgICAgQm9yZGVyICAgICAgICAgICAgICAgICpcbiAqICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICpcbiAqL1xuLyoqXG4gKiBHZXQgdmlzaWJsZSBhcmVhIG9mIGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZpc2libGVBcmVhKGluaXRBcmVhLCBzY3JvbGxlckxpc3QpIHtcbiAgdmFyIHZpc2libGVBcmVhID0gX29iamVjdFNwcmVhZCh7fSwgaW5pdEFyZWEpO1xuICAoc2Nyb2xsZXJMaXN0IHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uIChlbGUpIHtcbiAgICBpZiAoZWxlIGluc3RhbmNlb2YgSFRNTEJvZHlFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU2tpcCBpZiBzdGF0aWMgcG9zaXRpb24gd2hpY2ggd2lsbCBub3QgYWZmZWN0IHZpc2libGUgYXJlYVxuICAgIHZhciBfZ2V0V2luJGdldENvbXB1dGVkU3QyID0gZ2V0V2luKGVsZSkuZ2V0Q29tcHV0ZWRTdHlsZShlbGUpLFxuICAgICAgb3ZlcmZsb3cgPSBfZ2V0V2luJGdldENvbXB1dGVkU3QyLm92ZXJmbG93LFxuICAgICAgb3ZlcmZsb3dDbGlwTWFyZ2luID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Mi5vdmVyZmxvd0NsaXBNYXJnaW4sXG4gICAgICBib3JkZXJUb3BXaWR0aCA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIuYm9yZGVyVG9wV2lkdGgsXG4gICAgICBib3JkZXJCb3R0b21XaWR0aCA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIuYm9yZGVyQm90dG9tV2lkdGgsXG4gICAgICBib3JkZXJMZWZ0V2lkdGggPSBfZ2V0V2luJGdldENvbXB1dGVkU3QyLmJvcmRlckxlZnRXaWR0aCxcbiAgICAgIGJvcmRlclJpZ2h0V2lkdGggPSBfZ2V0V2luJGdldENvbXB1dGVkU3QyLmJvcmRlclJpZ2h0V2lkdGg7XG4gICAgdmFyIGVsZVJlY3QgPSBlbGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgdmFyIGVsZU91dEhlaWdodCA9IGVsZS5vZmZzZXRIZWlnaHQsXG4gICAgICBlbGVJbm5lckhlaWdodCA9IGVsZS5jbGllbnRIZWlnaHQsXG4gICAgICBlbGVPdXRXaWR0aCA9IGVsZS5vZmZzZXRXaWR0aCxcbiAgICAgIGVsZUlubmVyV2lkdGggPSBlbGUuY2xpZW50V2lkdGg7XG4gICAgdmFyIGJvcmRlclRvcE51bSA9IGdldFB4VmFsdWUoYm9yZGVyVG9wV2lkdGgpO1xuICAgIHZhciBib3JkZXJCb3R0b21OdW0gPSBnZXRQeFZhbHVlKGJvcmRlckJvdHRvbVdpZHRoKTtcbiAgICB2YXIgYm9yZGVyTGVmdE51bSA9IGdldFB4VmFsdWUoYm9yZGVyTGVmdFdpZHRoKTtcbiAgICB2YXIgYm9yZGVyUmlnaHROdW0gPSBnZXRQeFZhbHVlKGJvcmRlclJpZ2h0V2lkdGgpO1xuICAgIHZhciBzY2FsZVggPSB0b051bShNYXRoLnJvdW5kKGVsZVJlY3Qud2lkdGggLyBlbGVPdXRXaWR0aCAqIDEwMDApIC8gMTAwMCk7XG4gICAgdmFyIHNjYWxlWSA9IHRvTnVtKE1hdGgucm91bmQoZWxlUmVjdC5oZWlnaHQgLyBlbGVPdXRIZWlnaHQgKiAxMDAwKSAvIDEwMDApO1xuXG4gICAgLy8gT3JpZ2luYWwgdmlzaWJsZSBhcmVhXG4gICAgdmFyIGVsZVNjcm9sbFdpZHRoID0gKGVsZU91dFdpZHRoIC0gZWxlSW5uZXJXaWR0aCAtIGJvcmRlckxlZnROdW0gLSBib3JkZXJSaWdodE51bSkgKiBzY2FsZVg7XG4gICAgdmFyIGVsZVNjcm9sbEhlaWdodCA9IChlbGVPdXRIZWlnaHQgLSBlbGVJbm5lckhlaWdodCAtIGJvcmRlclRvcE51bSAtIGJvcmRlckJvdHRvbU51bSkgKiBzY2FsZVk7XG5cbiAgICAvLyBDdXQgYm9yZGVyIHNpemVcbiAgICB2YXIgc2NhbGVkQm9yZGVyVG9wV2lkdGggPSBib3JkZXJUb3BOdW0gKiBzY2FsZVk7XG4gICAgdmFyIHNjYWxlZEJvcmRlckJvdHRvbVdpZHRoID0gYm9yZGVyQm90dG9tTnVtICogc2NhbGVZO1xuICAgIHZhciBzY2FsZWRCb3JkZXJMZWZ0V2lkdGggPSBib3JkZXJMZWZ0TnVtICogc2NhbGVYO1xuICAgIHZhciBzY2FsZWRCb3JkZXJSaWdodFdpZHRoID0gYm9yZGVyUmlnaHROdW0gKiBzY2FsZVg7XG5cbiAgICAvLyBDbGlwIG1hcmdpblxuICAgIHZhciBjbGlwTWFyZ2luV2lkdGggPSAwO1xuICAgIHZhciBjbGlwTWFyZ2luSGVpZ2h0ID0gMDtcbiAgICBpZiAob3ZlcmZsb3cgPT09ICdjbGlwJykge1xuICAgICAgdmFyIGNsaXBOdW0gPSBnZXRQeFZhbHVlKG92ZXJmbG93Q2xpcE1hcmdpbik7XG4gICAgICBjbGlwTWFyZ2luV2lkdGggPSBjbGlwTnVtICogc2NhbGVYO1xuICAgICAgY2xpcE1hcmdpbkhlaWdodCA9IGNsaXBOdW0gKiBzY2FsZVk7XG4gICAgfVxuXG4gICAgLy8gUmVnaW9uXG4gICAgdmFyIGVsZUxlZnQgPSBlbGVSZWN0LnggKyBzY2FsZWRCb3JkZXJMZWZ0V2lkdGggLSBjbGlwTWFyZ2luV2lkdGg7XG4gICAgdmFyIGVsZVRvcCA9IGVsZVJlY3QueSArIHNjYWxlZEJvcmRlclRvcFdpZHRoIC0gY2xpcE1hcmdpbkhlaWdodDtcbiAgICB2YXIgZWxlUmlnaHQgPSBlbGVMZWZ0ICsgZWxlUmVjdC53aWR0aCArIDIgKiBjbGlwTWFyZ2luV2lkdGggLSBzY2FsZWRCb3JkZXJMZWZ0V2lkdGggLSBzY2FsZWRCb3JkZXJSaWdodFdpZHRoIC0gZWxlU2Nyb2xsV2lkdGg7XG4gICAgdmFyIGVsZUJvdHRvbSA9IGVsZVRvcCArIGVsZVJlY3QuaGVpZ2h0ICsgMiAqIGNsaXBNYXJnaW5IZWlnaHQgLSBzY2FsZWRCb3JkZXJUb3BXaWR0aCAtIHNjYWxlZEJvcmRlckJvdHRvbVdpZHRoIC0gZWxlU2Nyb2xsSGVpZ2h0O1xuICAgIHZpc2libGVBcmVhLmxlZnQgPSBNYXRoLm1heCh2aXNpYmxlQXJlYS5sZWZ0LCBlbGVMZWZ0KTtcbiAgICB2aXNpYmxlQXJlYS50b3AgPSBNYXRoLm1heCh2aXNpYmxlQXJlYS50b3AsIGVsZVRvcCk7XG4gICAgdmlzaWJsZUFyZWEucmlnaHQgPSBNYXRoLm1pbih2aXNpYmxlQXJlYS5yaWdodCwgZWxlUmlnaHQpO1xuICAgIHZpc2libGVBcmVhLmJvdHRvbSA9IE1hdGgubWluKHZpc2libGVBcmVhLmJvdHRvbSwgZWxlQm90dG9tKTtcbiAgfSk7XG4gIHJldHVybiB2aXNpYmxlQXJlYTtcbn0iLCJpbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgeyBpc0RPTSB9IGZyb20gXCJyYy11dGlsL2VzL0RvbS9maW5kRE9NTm9kZVwiO1xuaW1wb3J0IGlzVmlzaWJsZSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vaXNWaXNpYmxlXCI7XG5pbXBvcnQgdXNlRXZlbnQgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlRXZlbnRcIjtcbmltcG9ydCB1c2VMYXlvdXRFZmZlY3QgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlTGF5b3V0RWZmZWN0XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBjb2xsZWN0U2Nyb2xsZXIsIGdldFZpc2libGVBcmVhLCBnZXRXaW4sIHRvTnVtIH0gZnJvbSBcIi4uL3V0aWxcIjtcbmZ1bmN0aW9uIGdldFVuaXRPZmZzZXQoc2l6ZSkge1xuICB2YXIgb2Zmc2V0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwO1xuICB2YXIgb2Zmc2V0U3RyID0gXCJcIi5jb25jYXQob2Zmc2V0KTtcbiAgdmFyIGNlbGxzID0gb2Zmc2V0U3RyLm1hdGNoKC9eKC4qKVxcJSQvKTtcbiAgaWYgKGNlbGxzKSB7XG4gICAgcmV0dXJuIHNpemUgKiAocGFyc2VGbG9hdChjZWxsc1sxXSkgLyAxMDApO1xuICB9XG4gIHJldHVybiBwYXJzZUZsb2F0KG9mZnNldFN0cik7XG59XG5mdW5jdGlvbiBnZXROdW1iZXJPZmZzZXQocmVjdCwgb2Zmc2V0KSB7XG4gIHZhciBfcmVmID0gb2Zmc2V0IHx8IFtdLFxuICAgIF9yZWYyID0gX3NsaWNlZFRvQXJyYXkoX3JlZiwgMiksXG4gICAgb2Zmc2V0WCA9IF9yZWYyWzBdLFxuICAgIG9mZnNldFkgPSBfcmVmMlsxXTtcbiAgcmV0dXJuIFtnZXRVbml0T2Zmc2V0KHJlY3Qud2lkdGgsIG9mZnNldFgpLCBnZXRVbml0T2Zmc2V0KHJlY3QuaGVpZ2h0LCBvZmZzZXRZKV07XG59XG5mdW5jdGlvbiBzcGxpdFBvaW50cygpIHtcbiAgdmFyIHBvaW50cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogJyc7XG4gIHJldHVybiBbcG9pbnRzWzBdLCBwb2ludHNbMV1dO1xufVxuZnVuY3Rpb24gZ2V0QWxpZ25Qb2ludChyZWN0LCBwb2ludHMpIHtcbiAgdmFyIHRvcEJvdHRvbSA9IHBvaW50c1swXTtcbiAgdmFyIGxlZnRSaWdodCA9IHBvaW50c1sxXTtcbiAgdmFyIHg7XG4gIHZhciB5O1xuXG4gIC8vIFRvcCAmIEJvdHRvbVxuICBpZiAodG9wQm90dG9tID09PSAndCcpIHtcbiAgICB5ID0gcmVjdC55O1xuICB9IGVsc2UgaWYgKHRvcEJvdHRvbSA9PT0gJ2InKSB7XG4gICAgeSA9IHJlY3QueSArIHJlY3QuaGVpZ2h0O1xuICB9IGVsc2Uge1xuICAgIHkgPSByZWN0LnkgKyByZWN0LmhlaWdodCAvIDI7XG4gIH1cblxuICAvLyBMZWZ0ICYgUmlnaHRcbiAgaWYgKGxlZnRSaWdodCA9PT0gJ2wnKSB7XG4gICAgeCA9IHJlY3QueDtcbiAgfSBlbHNlIGlmIChsZWZ0UmlnaHQgPT09ICdyJykge1xuICAgIHggPSByZWN0LnggKyByZWN0LndpZHRoO1xuICB9IGVsc2Uge1xuICAgIHggPSByZWN0LnggKyByZWN0LndpZHRoIC8gMjtcbiAgfVxuICByZXR1cm4ge1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9O1xufVxuZnVuY3Rpb24gcmV2ZXJzZVBvaW50cyhwb2ludHMsIGluZGV4KSB7XG4gIHZhciByZXZlcnNlTWFwID0ge1xuICAgIHQ6ICdiJyxcbiAgICBiOiAndCcsXG4gICAgbDogJ3InLFxuICAgIHI6ICdsJ1xuICB9O1xuICByZXR1cm4gcG9pbnRzLm1hcChmdW5jdGlvbiAocG9pbnQsIGkpIHtcbiAgICBpZiAoaSA9PT0gaW5kZXgpIHtcbiAgICAgIHJldHVybiByZXZlcnNlTWFwW3BvaW50XSB8fCAnYyc7XG4gICAgfVxuICAgIHJldHVybiBwb2ludDtcbiAgfSkuam9pbignJyk7XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VBbGlnbihvcGVuLCBwb3B1cEVsZSwgdGFyZ2V0LCBwbGFjZW1lbnQsIGJ1aWx0aW5QbGFjZW1lbnRzLCBwb3B1cEFsaWduLCBvblBvcHVwQWxpZ24pIHtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKHtcbiAgICAgIHJlYWR5OiBmYWxzZSxcbiAgICAgIG9mZnNldFg6IDAsXG4gICAgICBvZmZzZXRZOiAwLFxuICAgICAgYXJyb3dYOiAwLFxuICAgICAgYXJyb3dZOiAwLFxuICAgICAgc2NhbGVYOiAxLFxuICAgICAgc2NhbGVZOiAxLFxuICAgICAgYWxpZ246IGJ1aWx0aW5QbGFjZW1lbnRzW3BsYWNlbWVudF0gfHwge31cbiAgICB9KSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICBvZmZzZXRJbmZvID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRPZmZzZXRJbmZvID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgdmFyIGFsaWduQ291bnRSZWYgPSBSZWFjdC51c2VSZWYoMCk7XG4gIHZhciBzY3JvbGxlckxpc3QgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXBvcHVwRWxlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0U2Nyb2xsZXIocG9wdXBFbGUpO1xuICB9LCBbcG9wdXBFbGVdKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09IEZsaXAgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gV2Ugd2lsbCBtZW1vIGZsaXAgaW5mby5cbiAgLy8gSWYgc2l6ZSBjaGFuZ2UgdG8gbWFrZSBmbGlwLCBpdCB3aWxsIG1lbW8gdGhlIGZsaXAgaW5mbyBhbmQgdXNlIGl0IGluIG5leHQgYWxpZ24uXG4gIHZhciBwcmV2RmxpcFJlZiA9IFJlYWN0LnVzZVJlZih7fSk7XG4gIHZhciByZXNldEZsaXBDYWNoZSA9IGZ1bmN0aW9uIHJlc2V0RmxpcENhY2hlKCkge1xuICAgIHByZXZGbGlwUmVmLmN1cnJlbnQgPSB7fTtcbiAgfTtcbiAgaWYgKCFvcGVuKSB7XG4gICAgcmVzZXRGbGlwQ2FjaGUoKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT0gQWxpZ24gPT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgb25BbGlnbiA9IHVzZUV2ZW50KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAocG9wdXBFbGUgJiYgdGFyZ2V0ICYmIG9wZW4pIHtcbiAgICAgIHZhciBwb3B1cEVsZW1lbnQgPSBwb3B1cEVsZTtcbiAgICAgIHZhciBvcmlnaW5MZWZ0ID0gcG9wdXBFbGVtZW50LnN0eWxlLmxlZnQ7XG4gICAgICB2YXIgb3JpZ2luVG9wID0gcG9wdXBFbGVtZW50LnN0eWxlLnRvcDtcbiAgICAgIHZhciBkb2MgPSBwb3B1cEVsZW1lbnQub3duZXJEb2N1bWVudDtcbiAgICAgIHZhciB3aW4gPSBnZXRXaW4ocG9wdXBFbGVtZW50KTtcblxuICAgICAgLy8gUGxhY2VtZW50XG4gICAgICB2YXIgcGxhY2VtZW50SW5mbyA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgYnVpbHRpblBsYWNlbWVudHNbcGxhY2VtZW50XSksIHBvcHVwQWxpZ24pO1xuXG4gICAgICAvLyBSZXNldCBmaXJzdFxuICAgICAgcG9wdXBFbGVtZW50LnN0eWxlLmxlZnQgPSAnMCc7XG4gICAgICBwb3B1cEVsZW1lbnQuc3R5bGUudG9wID0gJzAnO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgYWxpZ24gc3R5bGUsIHdlIHNob3VsZCBjb25zaWRlciBgdHJhbnNmb3JtYCBjYXNlXG4gICAgICB2YXIgdGFyZ2V0UmVjdDtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhcmdldCkpIHtcbiAgICAgICAgdGFyZ2V0UmVjdCA9IHtcbiAgICAgICAgICB4OiB0YXJnZXRbMF0sXG4gICAgICAgICAgeTogdGFyZ2V0WzFdLFxuICAgICAgICAgIHdpZHRoOiAwLFxuICAgICAgICAgIGhlaWdodDogMFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlY3QgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRhcmdldFJlY3QgPSB7XG4gICAgICAgICAgeDogcmVjdC54LFxuICAgICAgICAgIHk6IHJlY3QueSxcbiAgICAgICAgICB3aWR0aDogcmVjdC53aWR0aCxcbiAgICAgICAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICB2YXIgcG9wdXBSZWN0ID0gcG9wdXBFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgdmFyIF93aW4kZ2V0Q29tcHV0ZWRTdHlsZSA9IHdpbi5nZXRDb21wdXRlZFN0eWxlKHBvcHVwRWxlbWVudCksXG4gICAgICAgIHdpZHRoID0gX3dpbiRnZXRDb21wdXRlZFN0eWxlLndpZHRoLFxuICAgICAgICBoZWlnaHQgPSBfd2luJGdldENvbXB1dGVkU3R5bGUuaGVpZ2h0O1xuICAgICAgdmFyIF9kb2MkZG9jdW1lbnRFbGVtZW50ID0gZG9jLmRvY3VtZW50RWxlbWVudCxcbiAgICAgICAgY2xpZW50V2lkdGggPSBfZG9jJGRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCxcbiAgICAgICAgY2xpZW50SGVpZ2h0ID0gX2RvYyRkb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0LFxuICAgICAgICBzY3JvbGxXaWR0aCA9IF9kb2MkZG9jdW1lbnRFbGVtZW50LnNjcm9sbFdpZHRoLFxuICAgICAgICBzY3JvbGxIZWlnaHQgPSBfZG9jJGRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQsXG4gICAgICAgIHNjcm9sbFRvcCA9IF9kb2MkZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCxcbiAgICAgICAgc2Nyb2xsTGVmdCA9IF9kb2MkZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQ7XG4gICAgICB2YXIgcG9wdXBIZWlnaHQgPSBwb3B1cFJlY3QuaGVpZ2h0O1xuICAgICAgdmFyIHBvcHVwV2lkdGggPSBwb3B1cFJlY3Qud2lkdGg7XG4gICAgICB2YXIgdGFyZ2V0SGVpZ2h0ID0gdGFyZ2V0UmVjdC5oZWlnaHQ7XG4gICAgICB2YXIgdGFyZ2V0V2lkdGggPSB0YXJnZXRSZWN0LndpZHRoO1xuXG4gICAgICAvLyBHZXQgYm91bmRpbmcgb2YgdmlzaWJsZSBhcmVhXG4gICAgICB2YXIgdmlzaWJsZUFyZWEgPSBwbGFjZW1lbnRJbmZvLmh0bWxSZWdpb24gPT09ICdzY3JvbGwnID9cbiAgICAgIC8vIFNjcm9sbCByZWdpb24gc2hvdWxkIHRha2Ugc2Nyb2xsTGVmdCAmIHNjcm9sbFRvcCBpbnRvIGFjY291bnRcbiAgICAgIHtcbiAgICAgICAgbGVmdDogLXNjcm9sbExlZnQsXG4gICAgICAgIHRvcDogLXNjcm9sbFRvcCxcbiAgICAgICAgcmlnaHQ6IHNjcm9sbFdpZHRoIC0gc2Nyb2xsTGVmdCxcbiAgICAgICAgYm90dG9tOiBzY3JvbGxIZWlnaHQgLSBzY3JvbGxUb3BcbiAgICAgIH0gOiB7XG4gICAgICAgIGxlZnQ6IDAsXG4gICAgICAgIHRvcDogMCxcbiAgICAgICAgcmlnaHQ6IGNsaWVudFdpZHRoLFxuICAgICAgICBib3R0b206IGNsaWVudEhlaWdodFxuICAgICAgfTtcbiAgICAgIHZpc2libGVBcmVhID0gZ2V0VmlzaWJsZUFyZWEodmlzaWJsZUFyZWEsIHNjcm9sbGVyTGlzdCk7XG5cbiAgICAgIC8vIFJlc2V0IGJhY2tcbiAgICAgIHBvcHVwRWxlbWVudC5zdHlsZS5sZWZ0ID0gb3JpZ2luTGVmdDtcbiAgICAgIHBvcHVwRWxlbWVudC5zdHlsZS50b3AgPSBvcmlnaW5Ub3A7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBzY2FsZVxuICAgICAgdmFyIF9zY2FsZVggPSB0b051bShNYXRoLnJvdW5kKHBvcHVwV2lkdGggLyBwYXJzZUZsb2F0KHdpZHRoKSAqIDEwMDApIC8gMTAwMCk7XG4gICAgICB2YXIgX3NjYWxlWSA9IHRvTnVtKE1hdGgucm91bmQocG9wdXBIZWlnaHQgLyBwYXJzZUZsb2F0KGhlaWdodCkgKiAxMDAwKSAvIDEwMDApO1xuXG4gICAgICAvLyBObyBuZWVkIHRvIGFsaWduIHNpbmNlIGl0J3Mgbm90IHZpc2libGUgaW4gdmlld1xuICAgICAgaWYgKF9zY2FsZVggPT09IDAgfHwgX3NjYWxlWSA9PT0gMCB8fCBpc0RPTSh0YXJnZXQpICYmICFpc1Zpc2libGUodGFyZ2V0KSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIE9mZnNldFxuICAgICAgdmFyIG9mZnNldCA9IHBsYWNlbWVudEluZm8ub2Zmc2V0LFxuICAgICAgICB0YXJnZXRPZmZzZXQgPSBwbGFjZW1lbnRJbmZvLnRhcmdldE9mZnNldDtcbiAgICAgIHZhciBfZ2V0TnVtYmVyT2Zmc2V0ID0gZ2V0TnVtYmVyT2Zmc2V0KHBvcHVwUmVjdCwgb2Zmc2V0KSxcbiAgICAgICAgX2dldE51bWJlck9mZnNldDIgPSBfc2xpY2VkVG9BcnJheShfZ2V0TnVtYmVyT2Zmc2V0LCAyKSxcbiAgICAgICAgcG9wdXBPZmZzZXRYID0gX2dldE51bWJlck9mZnNldDJbMF0sXG4gICAgICAgIHBvcHVwT2Zmc2V0WSA9IF9nZXROdW1iZXJPZmZzZXQyWzFdO1xuICAgICAgdmFyIF9nZXROdW1iZXJPZmZzZXQzID0gZ2V0TnVtYmVyT2Zmc2V0KHRhcmdldFJlY3QsIHRhcmdldE9mZnNldCksXG4gICAgICAgIF9nZXROdW1iZXJPZmZzZXQ0ID0gX3NsaWNlZFRvQXJyYXkoX2dldE51bWJlck9mZnNldDMsIDIpLFxuICAgICAgICB0YXJnZXRPZmZzZXRYID0gX2dldE51bWJlck9mZnNldDRbMF0sXG4gICAgICAgIHRhcmdldE9mZnNldFkgPSBfZ2V0TnVtYmVyT2Zmc2V0NFsxXTtcbiAgICAgIHRhcmdldFJlY3QueCAtPSB0YXJnZXRPZmZzZXRYO1xuICAgICAgdGFyZ2V0UmVjdC55IC09IHRhcmdldE9mZnNldFk7XG5cbiAgICAgIC8vIFBvaW50c1xuICAgICAgdmFyIF9yZWYzID0gcGxhY2VtZW50SW5mby5wb2ludHMgfHwgW10sXG4gICAgICAgIF9yZWY0ID0gX3NsaWNlZFRvQXJyYXkoX3JlZjMsIDIpLFxuICAgICAgICBwb3B1cFBvaW50ID0gX3JlZjRbMF0sXG4gICAgICAgIHRhcmdldFBvaW50ID0gX3JlZjRbMV07XG4gICAgICB2YXIgdGFyZ2V0UG9pbnRzID0gc3BsaXRQb2ludHModGFyZ2V0UG9pbnQpO1xuICAgICAgdmFyIHBvcHVwUG9pbnRzID0gc3BsaXRQb2ludHMocG9wdXBQb2ludCk7XG4gICAgICB2YXIgdGFyZ2V0QWxpZ25Qb2ludCA9IGdldEFsaWduUG9pbnQodGFyZ2V0UmVjdCwgdGFyZ2V0UG9pbnRzKTtcbiAgICAgIHZhciBwb3B1cEFsaWduUG9pbnQgPSBnZXRBbGlnblBvaW50KHBvcHVwUmVjdCwgcG9wdXBQb2ludHMpO1xuXG4gICAgICAvLyBSZWFsIGFsaWduIGluZm8gbWF5IG5vdCBzYW1lIGFzIG9yaWdpbiBvbmVcbiAgICAgIHZhciBuZXh0QWxpZ25JbmZvID0gX29iamVjdFNwcmVhZCh7fSwgcGxhY2VtZW50SW5mbyk7XG5cbiAgICAgIC8vIE5leHQgT2Zmc2V0XG4gICAgICB2YXIgbmV4dE9mZnNldFggPSB0YXJnZXRBbGlnblBvaW50LnggLSBwb3B1cEFsaWduUG9pbnQueCArIHBvcHVwT2Zmc2V0WDtcbiAgICAgIHZhciBuZXh0T2Zmc2V0WSA9IHRhcmdldEFsaWduUG9pbnQueSAtIHBvcHVwQWxpZ25Qb2ludC55ICsgcG9wdXBPZmZzZXRZO1xuXG4gICAgICAvLyA9PT09PT09PT09PT09PSBJbnRlcnNlY3Rpb24gPT09PT09PT09PT09PT09XG4gICAgICAvLyBHZXQgYXJlYSBieSBwb3NpdGlvbi4gVXNlZCBmb3IgY2hlY2sgaWYgZmxpcCBhcmVhIGlzIGJldHRlclxuICAgICAgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEob2Zmc2V0WCwgb2Zmc2V0WSkge1xuICAgICAgICB2YXIgbCA9IHBvcHVwUmVjdC54ICsgb2Zmc2V0WDtcbiAgICAgICAgdmFyIHQgPSBwb3B1cFJlY3QueSArIG9mZnNldFk7XG4gICAgICAgIHZhciByID0gbCArIHBvcHVwV2lkdGg7XG4gICAgICAgIHZhciBiID0gdCArIHBvcHVwSGVpZ2h0O1xuICAgICAgICB2YXIgdmlzaWJsZUwgPSBNYXRoLm1heChsLCB2aXNpYmxlQXJlYS5sZWZ0KTtcbiAgICAgICAgdmFyIHZpc2libGVUID0gTWF0aC5tYXgodCwgdmlzaWJsZUFyZWEudG9wKTtcbiAgICAgICAgdmFyIHZpc2libGVSID0gTWF0aC5taW4ociwgdmlzaWJsZUFyZWEucmlnaHQpO1xuICAgICAgICB2YXIgdmlzaWJsZUIgPSBNYXRoLm1pbihiLCB2aXNpYmxlQXJlYS5ib3R0b20pO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgoMCwgKHZpc2libGVSIC0gdmlzaWJsZUwpICogKHZpc2libGVCIC0gdmlzaWJsZVQpKTtcbiAgICAgIH1cbiAgICAgIHZhciBvcmlnaW5JbnRlcnNlY3Rpb25WaXNpYmxlQXJlYSA9IGdldEludGVyc2VjdGlvblZpc2libGVBcmVhKG5leHRPZmZzZXRYLCBuZXh0T2Zmc2V0WSk7XG5cbiAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IE92ZXJmbG93ID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgdmFyIHRhcmdldEFsaWduUG9pbnRUTCA9IGdldEFsaWduUG9pbnQodGFyZ2V0UmVjdCwgWyd0JywgJ2wnXSk7XG4gICAgICB2YXIgcG9wdXBBbGlnblBvaW50VEwgPSBnZXRBbGlnblBvaW50KHBvcHVwUmVjdCwgWyd0JywgJ2wnXSk7XG4gICAgICB2YXIgdGFyZ2V0QWxpZ25Qb2ludEJSID0gZ2V0QWxpZ25Qb2ludCh0YXJnZXRSZWN0LCBbJ2InLCAnciddKTtcbiAgICAgIHZhciBwb3B1cEFsaWduUG9pbnRCUiA9IGdldEFsaWduUG9pbnQocG9wdXBSZWN0LCBbJ2InLCAnciddKTtcbiAgICAgIHZhciBvdmVyZmxvdyA9IHBsYWNlbWVudEluZm8ub3ZlcmZsb3cgfHwge307XG4gICAgICB2YXIgYWRqdXN0WCA9IG92ZXJmbG93LmFkanVzdFgsXG4gICAgICAgIGFkanVzdFkgPSBvdmVyZmxvdy5hZGp1c3RZLFxuICAgICAgICBzaGlmdFggPSBvdmVyZmxvdy5zaGlmdFgsXG4gICAgICAgIHNoaWZ0WSA9IG92ZXJmbG93LnNoaWZ0WTtcbiAgICAgIHZhciBzdXBwb3J0QWRqdXN0ID0gZnVuY3Rpb24gc3VwcG9ydEFkanVzdCh2YWwpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdib29sZWFuJykge1xuICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbCA+PSAwO1xuICAgICAgfTtcblxuICAgICAgLy8gUHJlcGFyZSBwb3NpdGlvblxuICAgICAgdmFyIG5leHRQb3B1cFk7XG4gICAgICB2YXIgbmV4dFBvcHVwQm90dG9tO1xuICAgICAgdmFyIG5leHRQb3B1cFg7XG4gICAgICB2YXIgbmV4dFBvcHVwUmlnaHQ7XG4gICAgICBmdW5jdGlvbiBzeW5jTmV4dFBvcHVwUG9zaXRpb24oKSB7XG4gICAgICAgIG5leHRQb3B1cFkgPSBwb3B1cFJlY3QueSArIG5leHRPZmZzZXRZO1xuICAgICAgICBuZXh0UG9wdXBCb3R0b20gPSBuZXh0UG9wdXBZICsgcG9wdXBIZWlnaHQ7XG4gICAgICAgIG5leHRQb3B1cFggPSBwb3B1cFJlY3QueCArIG5leHRPZmZzZXRYO1xuICAgICAgICBuZXh0UG9wdXBSaWdodCA9IG5leHRQb3B1cFggKyBwb3B1cFdpZHRoO1xuICAgICAgfVxuICAgICAgc3luY05leHRQb3B1cFBvc2l0aW9uKCk7XG5cbiAgICAgIC8vID4+Pj4+Pj4+Pj4gVG9wICYgQm90dG9tXG4gICAgICB2YXIgbmVlZEFkanVzdFkgPSBzdXBwb3J0QWRqdXN0KGFkanVzdFkpO1xuICAgICAgdmFyIHNhbWVUQiA9IHBvcHVwUG9pbnRzWzBdID09PSB0YXJnZXRQb2ludHNbMF07XG5cbiAgICAgIC8vIEJvdHRvbSB0byBUb3BcbiAgICAgIGlmIChuZWVkQWRqdXN0WSAmJiBwb3B1cFBvaW50c1swXSA9PT0gJ3QnICYmIChuZXh0UG9wdXBCb3R0b20gPiB2aXNpYmxlQXJlYS5ib3R0b20gfHwgcHJldkZsaXBSZWYuY3VycmVudC5idCkpIHtcbiAgICAgICAgdmFyIHRtcE5leHRPZmZzZXRZID0gbmV4dE9mZnNldFk7XG4gICAgICAgIGlmIChzYW1lVEIpIHtcbiAgICAgICAgICB0bXBOZXh0T2Zmc2V0WSAtPSBwb3B1cEhlaWdodCAtIHRhcmdldEhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0bXBOZXh0T2Zmc2V0WSA9IHRhcmdldEFsaWduUG9pbnRUTC55IC0gcG9wdXBBbGlnblBvaW50QlIueSAtIHBvcHVwT2Zmc2V0WTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEobmV4dE9mZnNldFgsIHRtcE5leHRPZmZzZXRZKSA+PSBvcmlnaW5JbnRlcnNlY3Rpb25WaXNpYmxlQXJlYSkge1xuICAgICAgICAgIHByZXZGbGlwUmVmLmN1cnJlbnQuYnQgPSB0cnVlO1xuICAgICAgICAgIG5leHRPZmZzZXRZID0gdG1wTmV4dE9mZnNldFk7XG4gICAgICAgICAgbmV4dEFsaWduSW5mby5wb2ludHMgPSBbcmV2ZXJzZVBvaW50cyhwb3B1cFBvaW50cywgMCksIHJldmVyc2VQb2ludHModGFyZ2V0UG9pbnRzLCAwKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC5idCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRvcCB0byBCb3R0b21cbiAgICAgIGlmIChuZWVkQWRqdXN0WSAmJiBwb3B1cFBvaW50c1swXSA9PT0gJ2InICYmIChuZXh0UG9wdXBZIDwgdmlzaWJsZUFyZWEudG9wIHx8IHByZXZGbGlwUmVmLmN1cnJlbnQudGIpKSB7XG4gICAgICAgIHZhciBfdG1wTmV4dE9mZnNldFkgPSBuZXh0T2Zmc2V0WTtcbiAgICAgICAgaWYgKHNhbWVUQikge1xuICAgICAgICAgIF90bXBOZXh0T2Zmc2V0WSArPSBwb3B1cEhlaWdodCAtIHRhcmdldEhlaWdodDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBfdG1wTmV4dE9mZnNldFkgPSB0YXJnZXRBbGlnblBvaW50QlIueSAtIHBvcHVwQWxpZ25Qb2ludFRMLnkgLSBwb3B1cE9mZnNldFk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdldEludGVyc2VjdGlvblZpc2libGVBcmVhKG5leHRPZmZzZXRYLCBfdG1wTmV4dE9mZnNldFkpID49IG9yaWdpbkludGVyc2VjdGlvblZpc2libGVBcmVhKSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC50YiA9IHRydWU7XG4gICAgICAgICAgbmV4dE9mZnNldFkgPSBfdG1wTmV4dE9mZnNldFk7XG4gICAgICAgICAgbmV4dEFsaWduSW5mby5wb2ludHMgPSBbcmV2ZXJzZVBvaW50cyhwb3B1cFBvaW50cywgMCksIHJldmVyc2VQb2ludHModGFyZ2V0UG9pbnRzLCAwKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC50YiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vID4+Pj4+Pj4+Pj4gTGVmdCAmIFJpZ2h0XG4gICAgICB2YXIgbmVlZEFkanVzdFggPSBzdXBwb3J0QWRqdXN0KGFkanVzdFgpO1xuXG4gICAgICAvLyA+Pj4+PiBGbGlwXG4gICAgICB2YXIgc2FtZUxSID0gcG9wdXBQb2ludHNbMV0gPT09IHRhcmdldFBvaW50c1sxXTtcblxuICAgICAgLy8gUmlnaHQgdG8gTGVmdFxuICAgICAgaWYgKG5lZWRBZGp1c3RYICYmIHBvcHVwUG9pbnRzWzFdID09PSAnbCcgJiYgKG5leHRQb3B1cFJpZ2h0ID4gdmlzaWJsZUFyZWEucmlnaHQgfHwgcHJldkZsaXBSZWYuY3VycmVudC5ybCkpIHtcbiAgICAgICAgdmFyIHRtcE5leHRPZmZzZXRYID0gbmV4dE9mZnNldFg7XG4gICAgICAgIGlmIChzYW1lTFIpIHtcbiAgICAgICAgICB0bXBOZXh0T2Zmc2V0WCAtPSBwb3B1cFdpZHRoIC0gdGFyZ2V0V2lkdGg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG1wTmV4dE9mZnNldFggPSB0YXJnZXRBbGlnblBvaW50VEwueCAtIHBvcHVwQWxpZ25Qb2ludEJSLnggLSBwb3B1cE9mZnNldFg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdldEludGVyc2VjdGlvblZpc2libGVBcmVhKHRtcE5leHRPZmZzZXRYLCBuZXh0T2Zmc2V0WSkgPj0gb3JpZ2luSW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEpIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LnJsID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0T2Zmc2V0WCA9IHRtcE5leHRPZmZzZXRYO1xuICAgICAgICAgIG5leHRBbGlnbkluZm8ucG9pbnRzID0gW3JldmVyc2VQb2ludHMocG9wdXBQb2ludHMsIDEpLCByZXZlcnNlUG9pbnRzKHRhcmdldFBvaW50cywgMSldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByZXZGbGlwUmVmLmN1cnJlbnQucmwgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBMZWZ0IHRvIFJpZ2h0XG4gICAgICBpZiAobmVlZEFkanVzdFggJiYgcG9wdXBQb2ludHNbMV0gPT09ICdyJyAmJiAobmV4dFBvcHVwWCA8IHZpc2libGVBcmVhLmxlZnQgfHwgcHJldkZsaXBSZWYuY3VycmVudC5scikpIHtcbiAgICAgICAgdmFyIF90bXBOZXh0T2Zmc2V0WCA9IG5leHRPZmZzZXRYO1xuICAgICAgICBpZiAoc2FtZUxSKSB7XG4gICAgICAgICAgX3RtcE5leHRPZmZzZXRYICs9IHBvcHVwV2lkdGggLSB0YXJnZXRXaWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBfdG1wTmV4dE9mZnNldFggPSB0YXJnZXRBbGlnblBvaW50QlIueCAtIHBvcHVwQWxpZ25Qb2ludFRMLnggLSBwb3B1cE9mZnNldFg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdldEludGVyc2VjdGlvblZpc2libGVBcmVhKF90bXBOZXh0T2Zmc2V0WCwgbmV4dE9mZnNldFkpID49IG9yaWdpbkludGVyc2VjdGlvblZpc2libGVBcmVhKSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC5sciA9IHRydWU7XG4gICAgICAgICAgbmV4dE9mZnNldFggPSBfdG1wTmV4dE9mZnNldFg7XG4gICAgICAgICAgbmV4dEFsaWduSW5mby5wb2ludHMgPSBbcmV2ZXJzZVBvaW50cyhwb3B1cFBvaW50cywgMSksIHJldmVyc2VQb2ludHModGFyZ2V0UG9pbnRzLCAxKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC5sciA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU2hpZnQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgc3luY05leHRQb3B1cFBvc2l0aW9uKCk7XG4gICAgICB2YXIgbnVtU2hpZnRYID0gc2hpZnRYID09PSB0cnVlID8gMCA6IHNoaWZ0WDtcbiAgICAgIGlmICh0eXBlb2YgbnVtU2hpZnRYID09PSAnbnVtYmVyJykge1xuICAgICAgICAvLyBMZWZ0XG4gICAgICAgIGlmIChuZXh0UG9wdXBYIDwgdmlzaWJsZUFyZWEubGVmdCkge1xuICAgICAgICAgIG5leHRPZmZzZXRYIC09IG5leHRQb3B1cFggLSB2aXNpYmxlQXJlYS5sZWZ0O1xuICAgICAgICAgIGlmICh0YXJnZXRSZWN0LnggKyB0YXJnZXRXaWR0aCA8IHZpc2libGVBcmVhLmxlZnQgKyBudW1TaGlmdFgpIHtcbiAgICAgICAgICAgIG5leHRPZmZzZXRYICs9IHRhcmdldFJlY3QueCAtIHZpc2libGVBcmVhLmxlZnQgKyB0YXJnZXRXaWR0aCAtIG51bVNoaWZ0WDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSaWdodFxuICAgICAgICBpZiAobmV4dFBvcHVwUmlnaHQgPiB2aXNpYmxlQXJlYS5yaWdodCkge1xuICAgICAgICAgIG5leHRPZmZzZXRYIC09IG5leHRQb3B1cFJpZ2h0IC0gdmlzaWJsZUFyZWEucmlnaHQ7XG4gICAgICAgICAgaWYgKHRhcmdldFJlY3QueCA+IHZpc2libGVBcmVhLnJpZ2h0IC0gbnVtU2hpZnRYKSB7XG4gICAgICAgICAgICBuZXh0T2Zmc2V0WCArPSB0YXJnZXRSZWN0LnggLSB2aXNpYmxlQXJlYS5yaWdodCArIG51bVNoaWZ0WDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHZhciBudW1TaGlmdFkgPSBzaGlmdFkgPT09IHRydWUgPyAwIDogc2hpZnRZO1xuICAgICAgaWYgKHR5cGVvZiBudW1TaGlmdFkgPT09ICdudW1iZXInKSB7XG4gICAgICAgIC8vIFRvcFxuICAgICAgICBpZiAobmV4dFBvcHVwWSA8IHZpc2libGVBcmVhLnRvcCkge1xuICAgICAgICAgIG5leHRPZmZzZXRZIC09IG5leHRQb3B1cFkgLSB2aXNpYmxlQXJlYS50b3A7XG4gICAgICAgICAgaWYgKHRhcmdldFJlY3QueSArIHRhcmdldEhlaWdodCA8IHZpc2libGVBcmVhLnRvcCArIG51bVNoaWZ0WSkge1xuICAgICAgICAgICAgbmV4dE9mZnNldFkgKz0gdGFyZ2V0UmVjdC55IC0gdmlzaWJsZUFyZWEudG9wICsgdGFyZ2V0SGVpZ2h0IC0gbnVtU2hpZnRZO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJvdHRvbVxuICAgICAgICBpZiAobmV4dFBvcHVwQm90dG9tID4gdmlzaWJsZUFyZWEuYm90dG9tKSB7XG4gICAgICAgICAgbmV4dE9mZnNldFkgLT0gbmV4dFBvcHVwQm90dG9tIC0gdmlzaWJsZUFyZWEuYm90dG9tO1xuICAgICAgICAgIGlmICh0YXJnZXRSZWN0LnkgPiB2aXNpYmxlQXJlYS5ib3R0b20gLSBudW1TaGlmdFkpIHtcbiAgICAgICAgICAgIG5leHRPZmZzZXRZICs9IHRhcmdldFJlY3QueSAtIHZpc2libGVBcmVhLmJvdHRvbSArIG51bVNoaWZ0WTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBBcnJvdyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAvLyBBcnJvdyBjZW50ZXIgYWxpZ25cbiAgICAgIHZhciBwb3B1cExlZnQgPSBwb3B1cFJlY3QueCArIG5leHRPZmZzZXRYO1xuICAgICAgdmFyIHBvcHVwUmlnaHQgPSBwb3B1cExlZnQgKyBwb3B1cFdpZHRoO1xuICAgICAgdmFyIHBvcHVwVG9wID0gcG9wdXBSZWN0LnkgKyBuZXh0T2Zmc2V0WTtcbiAgICAgIHZhciBwb3B1cEJvdHRvbSA9IHBvcHVwVG9wICsgcG9wdXBIZWlnaHQ7XG4gICAgICB2YXIgdGFyZ2V0TGVmdCA9IHRhcmdldFJlY3QueDtcbiAgICAgIHZhciB0YXJnZXRSaWdodCA9IHRhcmdldExlZnQgKyB0YXJnZXRXaWR0aDtcbiAgICAgIHZhciB0YXJnZXRUb3AgPSB0YXJnZXRSZWN0Lnk7XG4gICAgICB2YXIgdGFyZ2V0Qm90dG9tID0gdGFyZ2V0VG9wICsgdGFyZ2V0SGVpZ2h0O1xuICAgICAgdmFyIG1heExlZnQgPSBNYXRoLm1heChwb3B1cExlZnQsIHRhcmdldExlZnQpO1xuICAgICAgdmFyIG1pblJpZ2h0ID0gTWF0aC5taW4ocG9wdXBSaWdodCwgdGFyZ2V0UmlnaHQpO1xuICAgICAgdmFyIHhDZW50ZXIgPSAobWF4TGVmdCArIG1pblJpZ2h0KSAvIDI7XG4gICAgICB2YXIgbmV4dEFycm93WCA9IHhDZW50ZXIgLSBwb3B1cExlZnQ7XG4gICAgICB2YXIgbWF4VG9wID0gTWF0aC5tYXgocG9wdXBUb3AsIHRhcmdldFRvcCk7XG4gICAgICB2YXIgbWluQm90dG9tID0gTWF0aC5taW4ocG9wdXBCb3R0b20sIHRhcmdldEJvdHRvbSk7XG4gICAgICB2YXIgeUNlbnRlciA9IChtYXhUb3AgKyBtaW5Cb3R0b20pIC8gMjtcbiAgICAgIHZhciBuZXh0QXJyb3dZID0geUNlbnRlciAtIHBvcHVwVG9wO1xuICAgICAgb25Qb3B1cEFsaWduID09PSBudWxsIHx8IG9uUG9wdXBBbGlnbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25Qb3B1cEFsaWduKHBvcHVwRWxlLCBuZXh0QWxpZ25JbmZvKTtcbiAgICAgIHNldE9mZnNldEluZm8oe1xuICAgICAgICByZWFkeTogdHJ1ZSxcbiAgICAgICAgb2Zmc2V0WDogbmV4dE9mZnNldFggLyBfc2NhbGVYLFxuICAgICAgICBvZmZzZXRZOiBuZXh0T2Zmc2V0WSAvIF9zY2FsZVksXG4gICAgICAgIGFycm93WDogbmV4dEFycm93WCAvIF9zY2FsZVgsXG4gICAgICAgIGFycm93WTogbmV4dEFycm93WSAvIF9zY2FsZVksXG4gICAgICAgIHNjYWxlWDogX3NjYWxlWCxcbiAgICAgICAgc2NhbGVZOiBfc2NhbGVZLFxuICAgICAgICBhbGlnbjogbmV4dEFsaWduSW5mb1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbiAgdmFyIHRyaWdnZXJBbGlnbiA9IGZ1bmN0aW9uIHRyaWdnZXJBbGlnbigpIHtcbiAgICBhbGlnbkNvdW50UmVmLmN1cnJlbnQgKz0gMTtcbiAgICB2YXIgaWQgPSBhbGlnbkNvdW50UmVmLmN1cnJlbnQ7XG5cbiAgICAvLyBNZXJnZSBhbGwgYWxpZ24gcmVxdWlyZW1lbnQgaW50byBvbmUgZnJhbWVcbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChhbGlnbkNvdW50UmVmLmN1cnJlbnQgPT09IGlkKSB7XG4gICAgICAgIG9uQWxpZ24oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvLyBSZXNldCByZWFkeSBzdGF0dXMgd2hlbiBwbGFjZW1lbnQgJiBvcGVuIGNoYW5nZWRcbiAgdmFyIHJlc2V0UmVhZHkgPSBmdW5jdGlvbiByZXNldFJlYWR5KCkge1xuICAgIHNldE9mZnNldEluZm8oZnVuY3Rpb24gKG9yaSkge1xuICAgICAgcmV0dXJuIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgb3JpKSwge30sIHtcbiAgICAgICAgcmVhZHk6IGZhbHNlXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcbiAgdXNlTGF5b3V0RWZmZWN0KHJlc2V0UmVhZHksIFtwbGFjZW1lbnRdKTtcbiAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIHJlc2V0UmVhZHkoKTtcbiAgICB9XG4gIH0sIFtvcGVuXSk7XG4gIHJldHVybiBbb2Zmc2V0SW5mby5yZWFkeSwgb2Zmc2V0SW5mby5vZmZzZXRYLCBvZmZzZXRJbmZvLm9mZnNldFksIG9mZnNldEluZm8uYXJyb3dYLCBvZmZzZXRJbmZvLmFycm93WSwgb2Zmc2V0SW5mby5zY2FsZVgsIG9mZnNldEluZm8uc2NhbGVZLCBvZmZzZXRJbmZvLmFsaWduLCB0cmlnZ2VyQWxpZ25dO1xufSIsImltcG9ydCBfdG9Db25zdW1hYmxlQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5XCI7XG5pbXBvcnQgdXNlTGF5b3V0RWZmZWN0IGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUxheW91dEVmZmVjdFwiO1xuaW1wb3J0IHsgY29sbGVjdFNjcm9sbGVyLCBnZXRXaW4gfSBmcm9tIFwiLi4vdXRpbFwiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlV2F0Y2gob3BlbiwgdGFyZ2V0LCBwb3B1cCwgb25BbGlnbikge1xuICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChvcGVuICYmIHRhcmdldCAmJiBwb3B1cCkge1xuICAgICAgdmFyIHRhcmdldEVsZW1lbnQgPSB0YXJnZXQ7XG4gICAgICB2YXIgcG9wdXBFbGVtZW50ID0gcG9wdXA7XG4gICAgICB2YXIgdGFyZ2V0U2Nyb2xsTGlzdCA9IGNvbGxlY3RTY3JvbGxlcih0YXJnZXRFbGVtZW50KTtcbiAgICAgIHZhciBwb3B1cFNjcm9sbExpc3QgPSBjb2xsZWN0U2Nyb2xsZXIocG9wdXBFbGVtZW50KTtcbiAgICAgIHZhciB3aW4gPSBnZXRXaW4ocG9wdXBFbGVtZW50KTtcbiAgICAgIHZhciBtZXJnZWRMaXN0ID0gbmV3IFNldChbd2luXS5jb25jYXQoX3RvQ29uc3VtYWJsZUFycmF5KHRhcmdldFNjcm9sbExpc3QpLCBfdG9Db25zdW1hYmxlQXJyYXkocG9wdXBTY3JvbGxMaXN0KSkpO1xuICAgICAgZnVuY3Rpb24gbm90aWZ5U2Nyb2xsKCkge1xuICAgICAgICBvbkFsaWduKCk7XG4gICAgICB9XG4gICAgICBtZXJnZWRMaXN0LmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbGVyKSB7XG4gICAgICAgIHNjcm9sbGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG5vdGlmeVNjcm9sbCwge1xuICAgICAgICAgIHBhc3NpdmU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCBub3RpZnlTY3JvbGwsIHtcbiAgICAgICAgcGFzc2l2ZTogdHJ1ZVxuICAgICAgfSk7XG5cbiAgICAgIC8vIEZpcnN0IHRpbWUgYWx3YXlzIGRvIGFsaWduXG4gICAgICBvbkFsaWduKCk7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICBtZXJnZWRMaXN0LmZvckVhY2goZnVuY3Rpb24gKHNjcm9sbGVyKSB7XG4gICAgICAgICAgc2Nyb2xsZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgbm90aWZ5U2Nyb2xsKTtcbiAgICAgICAgICB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgbm90aWZ5U2Nyb2xsKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgfSwgW29wZW4sIHRhcmdldCwgcG9wdXBdKTtcbn0iLCJpbXBvcnQgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiO1xudmFyIF9leGNsdWRlZCA9IFtcImNoaWxkcmVuXCJdO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IHZhciBDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQoe30pO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW90aW9uUHJvdmlkZXIoX3JlZikge1xuICB2YXIgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuLFxuICAgIHByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKF9yZWYsIF9leGNsdWRlZCk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDb250ZXh0LlByb3ZpZGVyLCB7XG4gICAgdmFsdWU6IHByb3BzXG4gIH0sIGNoaWxkcmVuKTtcbn0iLCJpbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX2NyZWF0ZVN1cGVyIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVTdXBlclwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xudmFyIERvbVdyYXBwZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKERvbVdyYXBwZXIsIF9SZWFjdCRDb21wb25lbnQpO1xuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKERvbVdyYXBwZXIpO1xuICBmdW5jdGlvbiBEb21XcmFwcGVyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEb21XcmFwcGVyKTtcbiAgICByZXR1cm4gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cbiAgX2NyZWF0ZUNsYXNzKERvbVdyYXBwZXIsIFt7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIERvbVdyYXBwZXI7XG59KFJlYWN0LkNvbXBvbmVudCk7XG5leHBvcnQgZGVmYXVsdCBEb21XcmFwcGVyOyIsImV4cG9ydCB2YXIgU1RBVFVTX05PTkUgPSAnbm9uZSc7XG5leHBvcnQgdmFyIFNUQVRVU19BUFBFQVIgPSAnYXBwZWFyJztcbmV4cG9ydCB2YXIgU1RBVFVTX0VOVEVSID0gJ2VudGVyJztcbmV4cG9ydCB2YXIgU1RBVFVTX0xFQVZFID0gJ2xlYXZlJztcbmV4cG9ydCB2YXIgU1RFUF9OT05FID0gJ25vbmUnO1xuZXhwb3J0IHZhciBTVEVQX1BSRVBBUkUgPSAncHJlcGFyZSc7XG5leHBvcnQgdmFyIFNURVBfU1RBUlQgPSAnc3RhcnQnO1xuZXhwb3J0IHZhciBTVEVQX0FDVElWRSA9ICdhY3RpdmUnO1xuZXhwb3J0IHZhciBTVEVQX0FDVElWQVRFRCA9ICdlbmQnO1xuLyoqXG4gKiBVc2VkIGZvciBkaXNhYmxlZCBtb3Rpb24gY2FzZS5cbiAqIFByZXBhcmUgc3RhZ2Ugd2lsbCBzdGlsbCB3b3JrIGJ1dCBzdGFydCAmIGFjdGl2ZSB3aWxsIGJlIHNraXBwZWQuXG4gKi9cbmV4cG9ydCB2YXIgU1RFUF9QUkVQQVJFRCA9ICdwcmVwYXJlZCc7IiwiaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuaW1wb3J0IGNhblVzZURPTSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vY2FuVXNlRG9tXCI7XG4vLyA9PT09PT09PT09PT09PT09PSBUcmFuc2l0aW9uID09PT09PT09PT09PT09PT09XG4vLyBFdmVudCB3cmFwcGVyLiBDb3B5IGZyb20gcmVhY3Qgc291cmNlIGNvZGVcbmZ1bmN0aW9uIG1ha2VQcmVmaXhNYXAoc3R5bGVQcm9wLCBldmVudE5hbWUpIHtcbiAgdmFyIHByZWZpeGVzID0ge307XG4gIHByZWZpeGVzW3N0eWxlUHJvcC50b0xvd2VyQ2FzZSgpXSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpO1xuICBwcmVmaXhlc1tcIldlYmtpdFwiLmNvbmNhdChzdHlsZVByb3ApXSA9IFwid2Via2l0XCIuY29uY2F0KGV2ZW50TmFtZSk7XG4gIHByZWZpeGVzW1wiTW96XCIuY29uY2F0KHN0eWxlUHJvcCldID0gXCJtb3pcIi5jb25jYXQoZXZlbnROYW1lKTtcbiAgcHJlZml4ZXNbXCJtc1wiLmNvbmNhdChzdHlsZVByb3ApXSA9IFwiTVNcIi5jb25jYXQoZXZlbnROYW1lKTtcbiAgcHJlZml4ZXNbXCJPXCIuY29uY2F0KHN0eWxlUHJvcCldID0gXCJvXCIuY29uY2F0KGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgcmV0dXJuIHByZWZpeGVzO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldFZlbmRvclByZWZpeGVzKGRvbVN1cHBvcnQsIHdpbikge1xuICB2YXIgcHJlZml4ZXMgPSB7XG4gICAgYW5pbWF0aW9uZW5kOiBtYWtlUHJlZml4TWFwKCdBbmltYXRpb24nLCAnQW5pbWF0aW9uRW5kJyksXG4gICAgdHJhbnNpdGlvbmVuZDogbWFrZVByZWZpeE1hcCgnVHJhbnNpdGlvbicsICdUcmFuc2l0aW9uRW5kJylcbiAgfTtcbiAgaWYgKGRvbVN1cHBvcnQpIHtcbiAgICBpZiAoISgnQW5pbWF0aW9uRXZlbnQnIGluIHdpbikpIHtcbiAgICAgIGRlbGV0ZSBwcmVmaXhlcy5hbmltYXRpb25lbmQuYW5pbWF0aW9uO1xuICAgIH1cbiAgICBpZiAoISgnVHJhbnNpdGlvbkV2ZW50JyBpbiB3aW4pKSB7XG4gICAgICBkZWxldGUgcHJlZml4ZXMudHJhbnNpdGlvbmVuZC50cmFuc2l0aW9uO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcHJlZml4ZXM7XG59XG52YXIgdmVuZG9yUHJlZml4ZXMgPSBnZXRWZW5kb3JQcmVmaXhlcyhjYW5Vc2VET00oKSwgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fSk7XG52YXIgc3R5bGUgPSB7fTtcbmlmIChjYW5Vc2VET00oKSkge1xuICB2YXIgX2RvY3VtZW50JGNyZWF0ZUVsZW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHN0eWxlID0gX2RvY3VtZW50JGNyZWF0ZUVsZW1lLnN0eWxlO1xufVxudmFyIHByZWZpeGVkRXZlbnROYW1lcyA9IHt9O1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKGV2ZW50TmFtZSkge1xuICBpZiAocHJlZml4ZWRFdmVudE5hbWVzW2V2ZW50TmFtZV0pIHtcbiAgICByZXR1cm4gcHJlZml4ZWRFdmVudE5hbWVzW2V2ZW50TmFtZV07XG4gIH1cbiAgdmFyIHByZWZpeE1hcCA9IHZlbmRvclByZWZpeGVzW2V2ZW50TmFtZV07XG4gIGlmIChwcmVmaXhNYXApIHtcbiAgICB2YXIgc3R5bGVQcm9wTGlzdCA9IE9iamVjdC5rZXlzKHByZWZpeE1hcCk7XG4gICAgdmFyIGxlbiA9IHN0eWxlUHJvcExpc3QubGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpICs9IDEpIHtcbiAgICAgIHZhciBzdHlsZVByb3AgPSBzdHlsZVByb3BMaXN0W2ldO1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwcmVmaXhNYXAsIHN0eWxlUHJvcCkgJiYgc3R5bGVQcm9wIGluIHN0eWxlKSB7XG4gICAgICAgIHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdID0gcHJlZml4TWFwW3N0eWxlUHJvcF07XG4gICAgICAgIHJldHVybiBwcmVmaXhlZEV2ZW50TmFtZXNbZXZlbnROYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxudmFyIGludGVybmFsQW5pbWF0aW9uRW5kTmFtZSA9IGdldFZlbmRvclByZWZpeGVkRXZlbnROYW1lKCdhbmltYXRpb25lbmQnKTtcbnZhciBpbnRlcm5hbFRyYW5zaXRpb25FbmROYW1lID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ3RyYW5zaXRpb25lbmQnKTtcbmV4cG9ydCB2YXIgc3VwcG9ydFRyYW5zaXRpb24gPSAhIShpbnRlcm5hbEFuaW1hdGlvbkVuZE5hbWUgJiYgaW50ZXJuYWxUcmFuc2l0aW9uRW5kTmFtZSk7XG5leHBvcnQgdmFyIGFuaW1hdGlvbkVuZE5hbWUgPSBpbnRlcm5hbEFuaW1hdGlvbkVuZE5hbWUgfHwgJ2FuaW1hdGlvbmVuZCc7XG5leHBvcnQgdmFyIHRyYW5zaXRpb25FbmROYW1lID0gaW50ZXJuYWxUcmFuc2l0aW9uRW5kTmFtZSB8fCAndHJhbnNpdGlvbmVuZCc7XG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNpdGlvbk5hbWUodHJhbnNpdGlvbk5hbWUsIHRyYW5zaXRpb25UeXBlKSB7XG4gIGlmICghdHJhbnNpdGlvbk5hbWUpIHJldHVybiBudWxsO1xuICBpZiAoX3R5cGVvZih0cmFuc2l0aW9uTmFtZSkgPT09ICdvYmplY3QnKSB7XG4gICAgdmFyIHR5cGUgPSB0cmFuc2l0aW9uVHlwZS5yZXBsYWNlKC8tXFx3L2csIGZ1bmN0aW9uIChtYXRjaCkge1xuICAgICAgcmV0dXJuIG1hdGNoWzFdLnRvVXBwZXJDYXNlKCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRyYW5zaXRpb25OYW1lW3R5cGVdO1xuICB9XG4gIHJldHVybiBcIlwiLmNvbmNhdCh0cmFuc2l0aW9uTmFtZSwgXCItXCIpLmNvbmNhdCh0cmFuc2l0aW9uVHlwZSk7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlUmVmIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgYW5pbWF0aW9uRW5kTmFtZSwgdHJhbnNpdGlvbkVuZE5hbWUgfSBmcm9tIFwiLi4vdXRpbC9tb3Rpb25cIjtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgdmFyIGNhY2hlRWxlbWVudFJlZiA9IHVzZVJlZigpO1xuXG4gIC8vIENhY2hlIGNhbGxiYWNrXG4gIHZhciBjYWxsYmFja1JlZiA9IHVzZVJlZihjYWxsYmFjayk7XG4gIGNhbGxiYWNrUmVmLmN1cnJlbnQgPSBjYWxsYmFjaztcblxuICAvLyBJbnRlcm5hbCBtb3Rpb24gZXZlbnQgaGFuZGxlclxuICB2YXIgb25JbnRlcm5hbE1vdGlvbkVuZCA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uIChldmVudCkge1xuICAgIGNhbGxiYWNrUmVmLmN1cnJlbnQoZXZlbnQpO1xuICB9LCBbXSk7XG5cbiAgLy8gUmVtb3ZlIGV2ZW50c1xuICBmdW5jdGlvbiByZW1vdmVNb3Rpb25FdmVudHMoZWxlbWVudCkge1xuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZE5hbWUsIG9uSW50ZXJuYWxNb3Rpb25FbmQpO1xuICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGFuaW1hdGlvbkVuZE5hbWUsIG9uSW50ZXJuYWxNb3Rpb25FbmQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBhdGNoIGV2ZW50c1xuICBmdW5jdGlvbiBwYXRjaE1vdGlvbkV2ZW50cyhlbGVtZW50KSB7XG4gICAgaWYgKGNhY2hlRWxlbWVudFJlZi5jdXJyZW50ICYmIGNhY2hlRWxlbWVudFJlZi5jdXJyZW50ICE9PSBlbGVtZW50KSB7XG4gICAgICByZW1vdmVNb3Rpb25FdmVudHMoY2FjaGVFbGVtZW50UmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudCAmJiBlbGVtZW50ICE9PSBjYWNoZUVsZW1lbnRSZWYuY3VycmVudCkge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRyYW5zaXRpb25FbmROYW1lLCBvbkludGVybmFsTW90aW9uRW5kKTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihhbmltYXRpb25FbmROYW1lLCBvbkludGVybmFsTW90aW9uRW5kKTtcblxuICAgICAgLy8gU2F2ZSBhcyBjYWNoZSBpbiBjYXNlIGRvbSByZW1vdmVkIHRyaWdnZXIgYnkgYG1vdGlvbkRlYWRsaW5lYFxuICAgICAgY2FjaGVFbGVtZW50UmVmLmN1cnJlbnQgPSBlbGVtZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIENsZWFuIHVwIHdoZW4gcmVtb3ZlZFxuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZW1vdmVNb3Rpb25FdmVudHMoY2FjaGVFbGVtZW50UmVmLmN1cnJlbnQpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgcmV0dXJuIFtwYXRjaE1vdGlvbkV2ZW50cywgcmVtb3ZlTW90aW9uRXZlbnRzXTtcbn0pOyIsImltcG9ydCB7IHVzZUVmZmVjdCwgdXNlTGF5b3V0RWZmZWN0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNhblVzZURvbSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vY2FuVXNlRG9tXCI7XG5cbi8vIEl0J3Mgc2FmZSB0byB1c2UgYHVzZUxheW91dEVmZmVjdGAgYnV0IHRoZSB3YXJuaW5nIGlzIGFubm95aW5nXG52YXIgdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdCA9IGNhblVzZURvbSgpID8gdXNlTGF5b3V0RWZmZWN0IDogdXNlRWZmZWN0O1xuZXhwb3J0IGRlZmF1bHQgdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdDsiLCJ2YXIgcmFmID0gZnVuY3Rpb24gcmFmKGNhbGxiYWNrKSB7XG4gIHJldHVybiArc2V0VGltZW91dChjYWxsYmFjaywgMTYpO1xufTtcbnZhciBjYWYgPSBmdW5jdGlvbiBjYWYobnVtKSB7XG4gIHJldHVybiBjbGVhclRpbWVvdXQobnVtKTtcbn07XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ3JlcXVlc3RBbmltYXRpb25GcmFtZScgaW4gd2luZG93KSB7XG4gIHJhZiA9IGZ1bmN0aW9uIHJhZihjYWxsYmFjaykge1xuICAgIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNhbGxiYWNrKTtcbiAgfTtcbiAgY2FmID0gZnVuY3Rpb24gY2FmKGhhbmRsZSkge1xuICAgIHJldHVybiB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlKTtcbiAgfTtcbn1cbnZhciByYWZVVUlEID0gMDtcbnZhciByYWZJZHMgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBjbGVhbnVwKGlkKSB7XG4gIHJhZklkcy5kZWxldGUoaWQpO1xufVxudmFyIHdyYXBwZXJSYWYgPSBmdW5jdGlvbiB3cmFwcGVyUmFmKGNhbGxiYWNrKSB7XG4gIHZhciB0aW1lcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMTtcbiAgcmFmVVVJRCArPSAxO1xuICB2YXIgaWQgPSByYWZVVUlEO1xuICBmdW5jdGlvbiBjYWxsUmVmKGxlZnRUaW1lcykge1xuICAgIGlmIChsZWZ0VGltZXMgPT09IDApIHtcbiAgICAgIC8vIENsZWFuIHVwXG4gICAgICBjbGVhbnVwKGlkKTtcblxuICAgICAgLy8gVHJpZ2dlclxuICAgICAgY2FsbGJhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmV4dCByYWZcbiAgICAgIHZhciByZWFsSWQgPSByYWYoZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsUmVmKGxlZnRUaW1lcyAtIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEJpbmQgcmVhbCByYWYgaWRcbiAgICAgIHJhZklkcy5zZXQoaWQsIHJlYWxJZCk7XG4gICAgfVxuICB9XG4gIGNhbGxSZWYodGltZXMpO1xuICByZXR1cm4gaWQ7XG59O1xud3JhcHBlclJhZi5jYW5jZWwgPSBmdW5jdGlvbiAoaWQpIHtcbiAgdmFyIHJlYWxJZCA9IHJhZklkcy5nZXQoaWQpO1xuICBjbGVhbnVwKHJlYWxJZCk7XG4gIHJldHVybiBjYWYocmVhbElkKTtcbn07XG5leHBvcnQgZGVmYXVsdCB3cmFwcGVyUmFmOyIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCByYWYgZnJvbSBcInJjLXV0aWwvZXMvcmFmXCI7XG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKCkge1xuICB2YXIgbmV4dEZyYW1lUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICBmdW5jdGlvbiBjYW5jZWxOZXh0RnJhbWUoKSB7XG4gICAgcmFmLmNhbmNlbChuZXh0RnJhbWVSZWYuY3VycmVudCk7XG4gIH1cbiAgZnVuY3Rpb24gbmV4dEZyYW1lKGNhbGxiYWNrKSB7XG4gICAgdmFyIGRlbGF5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAyO1xuICAgIGNhbmNlbE5leHRGcmFtZSgpO1xuICAgIHZhciBuZXh0RnJhbWVJZCA9IHJhZihmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoZGVsYXkgPD0gMSkge1xuICAgICAgICBjYWxsYmFjayh7XG4gICAgICAgICAgaXNDYW5jZWxlZDogZnVuY3Rpb24gaXNDYW5jZWxlZCgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXh0RnJhbWVJZCAhPT0gbmV4dEZyYW1lUmVmLmN1cnJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRGcmFtZShjYWxsYmFjaywgZGVsYXkgLSAxKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBuZXh0RnJhbWVSZWYuY3VycmVudCA9IG5leHRGcmFtZUlkO1xuICB9XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNhbmNlbE5leHRGcmFtZSgpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgcmV0dXJuIFtuZXh0RnJhbWUsIGNhbmNlbE5leHRGcmFtZV07XG59KTsiLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCB1c2VTdGF0ZSBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VTdGF0ZVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgU1RFUF9BQ1RJVkFURUQsIFNURVBfQUNUSVZFLCBTVEVQX05PTkUsIFNURVBfUFJFUEFSRSwgU1RFUF9QUkVQQVJFRCwgU1RFUF9TVEFSVCB9IGZyb20gXCIuLi9pbnRlcmZhY2VcIjtcbmltcG9ydCB1c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0IGZyb20gXCIuL3VzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCB1c2VOZXh0RnJhbWUgZnJvbSBcIi4vdXNlTmV4dEZyYW1lXCI7XG52YXIgRlVMTF9TVEVQX1FVRVVFID0gW1NURVBfUFJFUEFSRSwgU1RFUF9TVEFSVCwgU1RFUF9BQ1RJVkUsIFNURVBfQUNUSVZBVEVEXTtcbnZhciBTSU1QTEVfU1RFUF9RVUVVRSA9IFtTVEVQX1BSRVBBUkUsIFNURVBfUFJFUEFSRURdO1xuXG4vKiogU2tpcCBjdXJyZW50IHN0ZXAgKi9cbmV4cG9ydCB2YXIgU2tpcFN0ZXAgPSBmYWxzZTtcbi8qKiBDdXJyZW50IHN0ZXAgc2hvdWxkIGJlIHVwZGF0ZSBpbiAqL1xuZXhwb3J0IHZhciBEb1N0ZXAgPSB0cnVlO1xuZXhwb3J0IGZ1bmN0aW9uIGlzQWN0aXZlKHN0ZXApIHtcbiAgcmV0dXJuIHN0ZXAgPT09IFNURVBfQUNUSVZFIHx8IHN0ZXAgPT09IFNURVBfQUNUSVZBVEVEO1xufVxuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChzdGF0dXMsIHByZXBhcmVPbmx5LCBjYWxsYmFjaykge1xuICB2YXIgX3VzZVN0YXRlID0gdXNlU3RhdGUoU1RFUF9OT05FKSxcbiAgICBfdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0YXRlLCAyKSxcbiAgICBzdGVwID0gX3VzZVN0YXRlMlswXSxcbiAgICBzZXRTdGVwID0gX3VzZVN0YXRlMlsxXTtcbiAgdmFyIF91c2VOZXh0RnJhbWUgPSB1c2VOZXh0RnJhbWUoKSxcbiAgICBfdXNlTmV4dEZyYW1lMiA9IF9zbGljZWRUb0FycmF5KF91c2VOZXh0RnJhbWUsIDIpLFxuICAgIG5leHRGcmFtZSA9IF91c2VOZXh0RnJhbWUyWzBdLFxuICAgIGNhbmNlbE5leHRGcmFtZSA9IF91c2VOZXh0RnJhbWUyWzFdO1xuICBmdW5jdGlvbiBzdGFydFF1ZXVlKCkge1xuICAgIHNldFN0ZXAoU1RFUF9QUkVQQVJFLCB0cnVlKTtcbiAgfVxuICB2YXIgU1RFUF9RVUVVRSA9IHByZXBhcmVPbmx5ID8gU0lNUExFX1NURVBfUVVFVUUgOiBGVUxMX1NURVBfUVVFVUU7XG4gIHVzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChzdGVwICE9PSBTVEVQX05PTkUgJiYgc3RlcCAhPT0gU1RFUF9BQ1RJVkFURUQpIHtcbiAgICAgIHZhciBpbmRleCA9IFNURVBfUVVFVUUuaW5kZXhPZihzdGVwKTtcbiAgICAgIHZhciBuZXh0U3RlcCA9IFNURVBfUVVFVUVbaW5kZXggKyAxXTtcbiAgICAgIHZhciByZXN1bHQgPSBjYWxsYmFjayhzdGVwKTtcbiAgICAgIGlmIChyZXN1bHQgPT09IFNraXBTdGVwKSB7XG4gICAgICAgIC8vIFNraXAgd2hlbiBubyBuZWVkZWRcbiAgICAgICAgc2V0U3RlcChuZXh0U3RlcCwgdHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKG5leHRTdGVwKSB7XG4gICAgICAgIC8vIERvIGFzIGZyYW1lIGZvciBzdGVwIHVwZGF0ZVxuICAgICAgICBuZXh0RnJhbWUoZnVuY3Rpb24gKGluZm8pIHtcbiAgICAgICAgICBmdW5jdGlvbiBkb05leHQoKSB7XG4gICAgICAgICAgICAvLyBTa2lwIHNpbmNlIGN1cnJlbnQgcXVldWUgaXMgb29kXG4gICAgICAgICAgICBpZiAoaW5mby5pc0NhbmNlbGVkKCkpIHJldHVybjtcbiAgICAgICAgICAgIHNldFN0ZXAobmV4dFN0ZXAsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSB0cnVlKSB7XG4gICAgICAgICAgICBkb05leHQoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gT25seSBwcm9taXNlIHNob3VsZCBiZSBhc3luY1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihkb05leHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LCBbc3RhdHVzLCBzdGVwXSk7XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNhbmNlbE5leHRGcmFtZSgpO1xuICAgIH07XG4gIH0sIFtdKTtcbiAgcmV0dXJuIFtzdGFydFF1ZXVlLCBzdGVwXTtcbn0pOyIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgdXNlU3RhdGUgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlU3RhdGVcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlUmVmIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgU1RBVFVTX0FQUEVBUiwgU1RBVFVTX0VOVEVSLCBTVEFUVVNfTEVBVkUsIFNUQVRVU19OT05FLCBTVEVQX0FDVElWRSwgU1RFUF9QUkVQQVJFLCBTVEVQX1BSRVBBUkVELCBTVEVQX1NUQVJUIH0gZnJvbSBcIi4uL2ludGVyZmFjZVwiO1xuaW1wb3J0IHVzZURvbU1vdGlvbkV2ZW50cyBmcm9tIFwiLi91c2VEb21Nb3Rpb25FdmVudHNcIjtcbmltcG9ydCB1c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0IGZyb20gXCIuL3VzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCB1c2VTdGVwUXVldWUsIHsgRG9TdGVwLCBpc0FjdGl2ZSwgU2tpcFN0ZXAgfSBmcm9tIFwiLi91c2VTdGVwUXVldWVcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZVN0YXR1cyhzdXBwb3J0TW90aW9uLCB2aXNpYmxlLCBnZXRFbGVtZW50LCBfcmVmKSB7XG4gIHZhciBfcmVmJG1vdGlvbkVudGVyID0gX3JlZi5tb3Rpb25FbnRlcixcbiAgICBtb3Rpb25FbnRlciA9IF9yZWYkbW90aW9uRW50ZXIgPT09IHZvaWQgMCA/IHRydWUgOiBfcmVmJG1vdGlvbkVudGVyLFxuICAgIF9yZWYkbW90aW9uQXBwZWFyID0gX3JlZi5tb3Rpb25BcHBlYXIsXG4gICAgbW90aW9uQXBwZWFyID0gX3JlZiRtb3Rpb25BcHBlYXIgPT09IHZvaWQgMCA/IHRydWUgOiBfcmVmJG1vdGlvbkFwcGVhcixcbiAgICBfcmVmJG1vdGlvbkxlYXZlID0gX3JlZi5tb3Rpb25MZWF2ZSxcbiAgICBtb3Rpb25MZWF2ZSA9IF9yZWYkbW90aW9uTGVhdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfcmVmJG1vdGlvbkxlYXZlLFxuICAgIG1vdGlvbkRlYWRsaW5lID0gX3JlZi5tb3Rpb25EZWFkbGluZSxcbiAgICBtb3Rpb25MZWF2ZUltbWVkaWF0ZWx5ID0gX3JlZi5tb3Rpb25MZWF2ZUltbWVkaWF0ZWx5LFxuICAgIG9uQXBwZWFyUHJlcGFyZSA9IF9yZWYub25BcHBlYXJQcmVwYXJlLFxuICAgIG9uRW50ZXJQcmVwYXJlID0gX3JlZi5vbkVudGVyUHJlcGFyZSxcbiAgICBvbkxlYXZlUHJlcGFyZSA9IF9yZWYub25MZWF2ZVByZXBhcmUsXG4gICAgb25BcHBlYXJTdGFydCA9IF9yZWYub25BcHBlYXJTdGFydCxcbiAgICBvbkVudGVyU3RhcnQgPSBfcmVmLm9uRW50ZXJTdGFydCxcbiAgICBvbkxlYXZlU3RhcnQgPSBfcmVmLm9uTGVhdmVTdGFydCxcbiAgICBvbkFwcGVhckFjdGl2ZSA9IF9yZWYub25BcHBlYXJBY3RpdmUsXG4gICAgb25FbnRlckFjdGl2ZSA9IF9yZWYub25FbnRlckFjdGl2ZSxcbiAgICBvbkxlYXZlQWN0aXZlID0gX3JlZi5vbkxlYXZlQWN0aXZlLFxuICAgIG9uQXBwZWFyRW5kID0gX3JlZi5vbkFwcGVhckVuZCxcbiAgICBvbkVudGVyRW5kID0gX3JlZi5vbkVudGVyRW5kLFxuICAgIG9uTGVhdmVFbmQgPSBfcmVmLm9uTGVhdmVFbmQsXG4gICAgb25WaXNpYmxlQ2hhbmdlZCA9IF9yZWYub25WaXNpYmxlQ2hhbmdlZDtcbiAgLy8gVXNlZCBmb3Igb3V0ZXIgcmVuZGVyIHVzYWdlIHRvIGF2b2lkIGB2aXNpYmxlOiBmYWxzZSAmIHN0YXR1czogbm9uZWAgdG8gcmVuZGVyIG5vdGhpbmdcbiAgdmFyIF91c2VTdGF0ZSA9IHVzZVN0YXRlKCksXG4gICAgX3VzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF91c2VTdGF0ZSwgMiksXG4gICAgYXN5bmNWaXNpYmxlID0gX3VzZVN0YXRlMlswXSxcbiAgICBzZXRBc3luY1Zpc2libGUgPSBfdXNlU3RhdGUyWzFdO1xuICB2YXIgX3VzZVN0YXRlMyA9IHVzZVN0YXRlKFNUQVRVU19OT05FKSxcbiAgICBfdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0YXRlMywgMiksXG4gICAgc3RhdHVzID0gX3VzZVN0YXRlNFswXSxcbiAgICBzZXRTdGF0dXMgPSBfdXNlU3RhdGU0WzFdO1xuICB2YXIgX3VzZVN0YXRlNSA9IHVzZVN0YXRlKG51bGwpLFxuICAgIF91c2VTdGF0ZTYgPSBfc2xpY2VkVG9BcnJheShfdXNlU3RhdGU1LCAyKSxcbiAgICBzdHlsZSA9IF91c2VTdGF0ZTZbMF0sXG4gICAgc2V0U3R5bGUgPSBfdXNlU3RhdGU2WzFdO1xuICB2YXIgbW91bnRlZFJlZiA9IHVzZVJlZihmYWxzZSk7XG4gIHZhciBkZWFkbGluZVJlZiA9IHVzZVJlZihudWxsKTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gRG9tIE5vZGUgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIGZ1bmN0aW9uIGdldERvbUVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIGdldEVsZW1lbnQoKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IE1vdGlvbiBFbmQgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGFjdGl2ZVJlZiA9IHVzZVJlZihmYWxzZSk7XG5cbiAgLyoqXG4gICAqIENsZWFuIHVwIHN0YXR1cyAmIHN0eWxlXG4gICAqL1xuICBmdW5jdGlvbiB1cGRhdGVNb3Rpb25FbmRTdGF0dXMoKSB7XG4gICAgc2V0U3RhdHVzKFNUQVRVU19OT05FLCB0cnVlKTtcbiAgICBzZXRTdHlsZShudWxsLCB0cnVlKTtcbiAgfVxuICBmdW5jdGlvbiBvbkludGVybmFsTW90aW9uRW5kKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBnZXREb21FbGVtZW50KCk7XG4gICAgaWYgKGV2ZW50ICYmICFldmVudC5kZWFkbGluZSAmJiBldmVudC50YXJnZXQgIT09IGVsZW1lbnQpIHtcbiAgICAgIC8vIGV2ZW50IGV4aXN0c1xuICAgICAgLy8gbm90IGluaXRpYXRlZCBieSBkZWFkbGluZVxuICAgICAgLy8gdHJhbnNpdGlvbkVuZCBub3QgZmlyZWQgYnkgaW5uZXIgZWxlbWVudHNcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIGN1cnJlbnRBY3RpdmUgPSBhY3RpdmVSZWYuY3VycmVudDtcbiAgICB2YXIgY2FuRW5kO1xuICAgIGlmIChzdGF0dXMgPT09IFNUQVRVU19BUFBFQVIgJiYgY3VycmVudEFjdGl2ZSkge1xuICAgICAgY2FuRW5kID0gb25BcHBlYXJFbmQgPT09IG51bGwgfHwgb25BcHBlYXJFbmQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uQXBwZWFyRW5kKGVsZW1lbnQsIGV2ZW50KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gU1RBVFVTX0VOVEVSICYmIGN1cnJlbnRBY3RpdmUpIHtcbiAgICAgIGNhbkVuZCA9IG9uRW50ZXJFbmQgPT09IG51bGwgfHwgb25FbnRlckVuZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25FbnRlckVuZChlbGVtZW50LCBldmVudCk7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IFNUQVRVU19MRUFWRSAmJiBjdXJyZW50QWN0aXZlKSB7XG4gICAgICBjYW5FbmQgPSBvbkxlYXZlRW5kID09PSBudWxsIHx8IG9uTGVhdmVFbmQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uTGVhdmVFbmQoZWxlbWVudCwgZXZlbnQpO1xuICAgIH1cblxuICAgIC8vIE9ubHkgdXBkYXRlIHN0YXR1cyB3aGVuIGBjYW5FbmRgIGFuZCBub3QgZGVzdHJveWVkXG4gICAgaWYgKHN0YXR1cyAhPT0gU1RBVFVTX05PTkUgJiYgY3VycmVudEFjdGl2ZSAmJiBjYW5FbmQgIT09IGZhbHNlKSB7XG4gICAgICB1cGRhdGVNb3Rpb25FbmRTdGF0dXMoKTtcbiAgICB9XG4gIH1cbiAgdmFyIF91c2VEb21Nb3Rpb25FdmVudHMgPSB1c2VEb21Nb3Rpb25FdmVudHMob25JbnRlcm5hbE1vdGlvbkVuZCksXG4gICAgX3VzZURvbU1vdGlvbkV2ZW50czIgPSBfc2xpY2VkVG9BcnJheShfdXNlRG9tTW90aW9uRXZlbnRzLCAxKSxcbiAgICBwYXRjaE1vdGlvbkV2ZW50cyA9IF91c2VEb21Nb3Rpb25FdmVudHMyWzBdO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFN0ZXAgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGdldEV2ZW50SGFuZGxlcnMgPSBmdW5jdGlvbiBnZXRFdmVudEhhbmRsZXJzKHRhcmdldFN0YXR1cykge1xuICAgIHZhciBfcmVmMiwgX3JlZjMsIF9yZWY0O1xuICAgIHN3aXRjaCAodGFyZ2V0U3RhdHVzKSB7XG4gICAgICBjYXNlIFNUQVRVU19BUFBFQVI6XG4gICAgICAgIHJldHVybiBfcmVmMiA9IHt9LCBfZGVmaW5lUHJvcGVydHkoX3JlZjIsIFNURVBfUFJFUEFSRSwgb25BcHBlYXJQcmVwYXJlKSwgX2RlZmluZVByb3BlcnR5KF9yZWYyLCBTVEVQX1NUQVJULCBvbkFwcGVhclN0YXJ0KSwgX2RlZmluZVByb3BlcnR5KF9yZWYyLCBTVEVQX0FDVElWRSwgb25BcHBlYXJBY3RpdmUpLCBfcmVmMjtcbiAgICAgIGNhc2UgU1RBVFVTX0VOVEVSOlxuICAgICAgICByZXR1cm4gX3JlZjMgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9yZWYzLCBTVEVQX1BSRVBBUkUsIG9uRW50ZXJQcmVwYXJlKSwgX2RlZmluZVByb3BlcnR5KF9yZWYzLCBTVEVQX1NUQVJULCBvbkVudGVyU3RhcnQpLCBfZGVmaW5lUHJvcGVydHkoX3JlZjMsIFNURVBfQUNUSVZFLCBvbkVudGVyQWN0aXZlKSwgX3JlZjM7XG4gICAgICBjYXNlIFNUQVRVU19MRUFWRTpcbiAgICAgICAgcmV0dXJuIF9yZWY0ID0ge30sIF9kZWZpbmVQcm9wZXJ0eShfcmVmNCwgU1RFUF9QUkVQQVJFLCBvbkxlYXZlUHJlcGFyZSksIF9kZWZpbmVQcm9wZXJ0eShfcmVmNCwgU1RFUF9TVEFSVCwgb25MZWF2ZVN0YXJ0KSwgX2RlZmluZVByb3BlcnR5KF9yZWY0LCBTVEVQX0FDVElWRSwgb25MZWF2ZUFjdGl2ZSksIF9yZWY0O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgfTtcbiAgdmFyIGV2ZW50SGFuZGxlcnMgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZ2V0RXZlbnRIYW5kbGVycyhzdGF0dXMpO1xuICB9LCBbc3RhdHVzXSk7XG4gIHZhciBfdXNlU3RlcFF1ZXVlID0gdXNlU3RlcFF1ZXVlKHN0YXR1cywgIXN1cHBvcnRNb3Rpb24sIGZ1bmN0aW9uIChuZXdTdGVwKSB7XG4gICAgICAvLyBPbmx5IHByZXBhcmUgc3RlcCBjYW4gYmUgc2tpcFxuICAgICAgaWYgKG5ld1N0ZXAgPT09IFNURVBfUFJFUEFSRSkge1xuICAgICAgICB2YXIgb25QcmVwYXJlID0gZXZlbnRIYW5kbGVyc1tTVEVQX1BSRVBBUkVdO1xuICAgICAgICBpZiAoIW9uUHJlcGFyZSkge1xuICAgICAgICAgIHJldHVybiBTa2lwU3RlcDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb25QcmVwYXJlKGdldERvbUVsZW1lbnQoKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlc3Qgc3RlcCBpcyBzeW5jIHVwZGF0ZVxuICAgICAgaWYgKHN0ZXAgaW4gZXZlbnRIYW5kbGVycykge1xuICAgICAgICB2YXIgX2V2ZW50SGFuZGxlcnMkc3RlcDtcbiAgICAgICAgc2V0U3R5bGUoKChfZXZlbnRIYW5kbGVycyRzdGVwID0gZXZlbnRIYW5kbGVyc1tzdGVwXSkgPT09IG51bGwgfHwgX2V2ZW50SGFuZGxlcnMkc3RlcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2V2ZW50SGFuZGxlcnMkc3RlcC5jYWxsKGV2ZW50SGFuZGxlcnMsIGdldERvbUVsZW1lbnQoKSwgbnVsbCkpIHx8IG51bGwpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ZXAgPT09IFNURVBfQUNUSVZFKSB7XG4gICAgICAgIC8vIFBhdGNoIGV2ZW50cyB3aGVuIG1vdGlvbiBuZWVkZWRcbiAgICAgICAgcGF0Y2hNb3Rpb25FdmVudHMoZ2V0RG9tRWxlbWVudCgpKTtcbiAgICAgICAgaWYgKG1vdGlvbkRlYWRsaW5lID4gMCkge1xuICAgICAgICAgIGNsZWFyVGltZW91dChkZWFkbGluZVJlZi5jdXJyZW50KTtcbiAgICAgICAgICBkZWFkbGluZVJlZi5jdXJyZW50ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBvbkludGVybmFsTW90aW9uRW5kKHtcbiAgICAgICAgICAgICAgZGVhZGxpbmU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0sIG1vdGlvbkRlYWRsaW5lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0ZXAgPT09IFNURVBfUFJFUEFSRUQpIHtcbiAgICAgICAgdXBkYXRlTW90aW9uRW5kU3RhdHVzKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gRG9TdGVwO1xuICAgIH0pLFxuICAgIF91c2VTdGVwUXVldWUyID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0ZXBRdWV1ZSwgMiksXG4gICAgc3RhcnRTdGVwID0gX3VzZVN0ZXBRdWV1ZTJbMF0sXG4gICAgc3RlcCA9IF91c2VTdGVwUXVldWUyWzFdO1xuICB2YXIgYWN0aXZlID0gaXNBY3RpdmUoc3RlcCk7XG4gIGFjdGl2ZVJlZi5jdXJyZW50ID0gYWN0aXZlO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU3RhdHVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gVXBkYXRlIHdpdGggbmV3IHN0YXR1c1xuICB1c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBzZXRBc3luY1Zpc2libGUodmlzaWJsZSk7XG4gICAgdmFyIGlzTW91bnRlZCA9IG1vdW50ZWRSZWYuY3VycmVudDtcbiAgICBtb3VudGVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgLy8gaWYgKCFzdXBwb3J0TW90aW9uKSB7XG4gICAgLy8gICByZXR1cm47XG4gICAgLy8gfVxuXG4gICAgdmFyIG5leHRTdGF0dXM7XG5cbiAgICAvLyBBcHBlYXJcbiAgICBpZiAoIWlzTW91bnRlZCAmJiB2aXNpYmxlICYmIG1vdGlvbkFwcGVhcikge1xuICAgICAgbmV4dFN0YXR1cyA9IFNUQVRVU19BUFBFQVI7XG4gICAgfVxuXG4gICAgLy8gRW50ZXJcbiAgICBpZiAoaXNNb3VudGVkICYmIHZpc2libGUgJiYgbW90aW9uRW50ZXIpIHtcbiAgICAgIG5leHRTdGF0dXMgPSBTVEFUVVNfRU5URVI7XG4gICAgfVxuXG4gICAgLy8gTGVhdmVcbiAgICBpZiAoaXNNb3VudGVkICYmICF2aXNpYmxlICYmIG1vdGlvbkxlYXZlIHx8ICFpc01vdW50ZWQgJiYgbW90aW9uTGVhdmVJbW1lZGlhdGVseSAmJiAhdmlzaWJsZSAmJiBtb3Rpb25MZWF2ZSkge1xuICAgICAgbmV4dFN0YXR1cyA9IFNUQVRVU19MRUFWRTtcbiAgICB9XG4gICAgdmFyIG5leHRFdmVudEhhbmRsZXJzID0gZ2V0RXZlbnRIYW5kbGVycyhuZXh0U3RhdHVzKTtcblxuICAgIC8vIFVwZGF0ZSB0byBuZXh0IHN0YXR1c1xuICAgIGlmIChuZXh0U3RhdHVzICYmIChzdXBwb3J0TW90aW9uIHx8IG5leHRFdmVudEhhbmRsZXJzW1NURVBfUFJFUEFSRV0pKSB7XG4gICAgICBzZXRTdGF0dXMobmV4dFN0YXR1cyk7XG4gICAgICBzdGFydFN0ZXAoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gU2V0IGJhY2sgaW4gY2FzZSBubyBtb3Rpb24gYnV0IHByZXYgc3RhdHVzIGhhcyBwcmVwYXJlIHN0ZXBcbiAgICAgIHNldFN0YXR1cyhTVEFUVVNfTk9ORSk7XG4gICAgfVxuICB9LCBbdmlzaWJsZV0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gRWZmZWN0ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gUmVzZXQgd2hlbiBtb3Rpb24gY2hhbmdlZFxuICB1c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmIChcbiAgICAvLyBDYW5jZWwgYXBwZWFyXG4gICAgc3RhdHVzID09PSBTVEFUVVNfQVBQRUFSICYmICFtb3Rpb25BcHBlYXIgfHxcbiAgICAvLyBDYW5jZWwgZW50ZXJcbiAgICBzdGF0dXMgPT09IFNUQVRVU19FTlRFUiAmJiAhbW90aW9uRW50ZXIgfHxcbiAgICAvLyBDYW5jZWwgbGVhdmVcbiAgICBzdGF0dXMgPT09IFNUQVRVU19MRUFWRSAmJiAhbW90aW9uTGVhdmUpIHtcbiAgICAgIHNldFN0YXR1cyhTVEFUVVNfTk9ORSk7XG4gICAgfVxuICB9LCBbbW90aW9uQXBwZWFyLCBtb3Rpb25FbnRlciwgbW90aW9uTGVhdmVdKTtcbiAgdXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgbW91bnRlZFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICBjbGVhclRpbWVvdXQoZGVhZGxpbmVSZWYuY3VycmVudCk7XG4gICAgfTtcbiAgfSwgW10pO1xuXG4gIC8vIFRyaWdnZXIgYG9uVmlzaWJsZUNoYW5nZWRgXG4gIHZhciBmaXJzdE1vdW50Q2hhbmdlUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgdXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAvLyBbdmlzaWJsZSAmIG1vdGlvbiBub3QgZW5kXSA9PiBbIXZpc2libGUgJiBtb3Rpb24gZW5kXSBzdGlsbCBuZWVkIHRyaWdnZXIgb25WaXNpYmxlQ2hhbmdlZFxuICAgIGlmIChhc3luY1Zpc2libGUpIHtcbiAgICAgIGZpcnN0TW91bnRDaGFuZ2VSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfVxuICAgIGlmIChhc3luY1Zpc2libGUgIT09IHVuZGVmaW5lZCAmJiBzdGF0dXMgPT09IFNUQVRVU19OT05FKSB7XG4gICAgICAvLyBTa2lwIGZpcnN0IHJlbmRlciBpcyBpbnZpc2libGUgc2luY2UgaXQncyBub3RoaW5nIGNoYW5nZWRcbiAgICAgIGlmIChmaXJzdE1vdW50Q2hhbmdlUmVmLmN1cnJlbnQgfHwgYXN5bmNWaXNpYmxlKSB7XG4gICAgICAgIG9uVmlzaWJsZUNoYW5nZWQgPT09IG51bGwgfHwgb25WaXNpYmxlQ2hhbmdlZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25WaXNpYmxlQ2hhbmdlZChhc3luY1Zpc2libGUpO1xuICAgICAgfVxuICAgICAgZmlyc3RNb3VudENoYW5nZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gIH0sIFthc3luY1Zpc2libGUsIHN0YXR1c10pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU3R5bGVzID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG1lcmdlZFN0eWxlID0gc3R5bGU7XG4gIGlmIChldmVudEhhbmRsZXJzW1NURVBfUFJFUEFSRV0gJiYgc3RlcCA9PT0gU1RFUF9TVEFSVCkge1xuICAgIG1lcmdlZFN0eWxlID0gX29iamVjdFNwcmVhZCh7XG4gICAgICB0cmFuc2l0aW9uOiAnbm9uZSdcbiAgICB9LCBtZXJnZWRTdHlsZSk7XG4gIH1cbiAgcmV0dXJuIFtzdGF0dXMsIHN0ZXAsIG1lcmdlZFN0eWxlLCBhc3luY1Zpc2libGUgIT09IG51bGwgJiYgYXN5bmNWaXNpYmxlICE9PSB2b2lkIDAgPyBhc3luY1Zpc2libGUgOiB2aXNpYmxlXTtcbn0iLCJpbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuLyogZXNsaW50LWRpc2FibGUgcmVhY3QvZGVmYXVsdC1wcm9wcy1tYXRjaC1wcm9wLXR5cGVzLCByZWFjdC9uby1tdWx0aS1jb21wLCByZWFjdC9wcm9wLXR5cGVzICovXG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBmaW5kRE9NTm9kZSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vZmluZERPTU5vZGVcIjtcbmltcG9ydCB7IGZpbGxSZWYsIHN1cHBvcnRSZWYgfSBmcm9tIFwicmMtdXRpbC9lcy9yZWZcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZVJlZiB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0XCI7XG5pbXBvcnQgRG9tV3JhcHBlciBmcm9tIFwiLi9Eb21XcmFwcGVyXCI7XG5pbXBvcnQgdXNlU3RhdHVzIGZyb20gXCIuL2hvb2tzL3VzZVN0YXR1c1wiO1xuaW1wb3J0IHsgaXNBY3RpdmUgfSBmcm9tIFwiLi9ob29rcy91c2VTdGVwUXVldWVcIjtcbmltcG9ydCB7IFNUQVRVU19OT05FLCBTVEVQX1BSRVBBUkUsIFNURVBfU1RBUlQgfSBmcm9tIFwiLi9pbnRlcmZhY2VcIjtcbmltcG9ydCB7IGdldFRyYW5zaXRpb25OYW1lLCBzdXBwb3J0VHJhbnNpdGlvbiB9IGZyb20gXCIuL3V0aWwvbW90aW9uXCI7XG4vKipcbiAqIGB0cmFuc2l0aW9uU3VwcG9ydGAgaXMgdXNlZCBmb3Igbm9uZSB0cmFuc2l0aW9uIHRlc3QgY2FzZS5cbiAqIERlZmF1bHQgd2UgdXNlIGJyb3dzZXIgdHJhbnNpdGlvbiBldmVudCBzdXBwb3J0IGNoZWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuQ1NTTW90aW9uKGNvbmZpZykge1xuICB2YXIgdHJhbnNpdGlvblN1cHBvcnQgPSBjb25maWc7XG4gIGlmIChfdHlwZW9mKGNvbmZpZykgPT09ICdvYmplY3QnKSB7XG4gICAgdHJhbnNpdGlvblN1cHBvcnQgPSBjb25maWcudHJhbnNpdGlvblN1cHBvcnQ7XG4gIH1cbiAgZnVuY3Rpb24gaXNTdXBwb3J0VHJhbnNpdGlvbihwcm9wcywgY29udGV4dE1vdGlvbikge1xuICAgIHJldHVybiAhIShwcm9wcy5tb3Rpb25OYW1lICYmIHRyYW5zaXRpb25TdXBwb3J0ICYmIGNvbnRleHRNb3Rpb24gIT09IGZhbHNlKTtcbiAgfVxuICB2YXIgQ1NTTW90aW9uID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgICB2YXIgX3Byb3BzJHZpc2libGUgPSBwcm9wcy52aXNpYmxlLFxuICAgICAgdmlzaWJsZSA9IF9wcm9wcyR2aXNpYmxlID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJHZpc2libGUsXG4gICAgICBfcHJvcHMkcmVtb3ZlT25MZWF2ZSA9IHByb3BzLnJlbW92ZU9uTGVhdmUsXG4gICAgICByZW1vdmVPbkxlYXZlID0gX3Byb3BzJHJlbW92ZU9uTGVhdmUgPT09IHZvaWQgMCA/IHRydWUgOiBfcHJvcHMkcmVtb3ZlT25MZWF2ZSxcbiAgICAgIGZvcmNlUmVuZGVyID0gcHJvcHMuZm9yY2VSZW5kZXIsXG4gICAgICBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgICAgbW90aW9uTmFtZSA9IHByb3BzLm1vdGlvbk5hbWUsXG4gICAgICBsZWF2ZWRDbGFzc05hbWUgPSBwcm9wcy5sZWF2ZWRDbGFzc05hbWUsXG4gICAgICBldmVudFByb3BzID0gcHJvcHMuZXZlbnRQcm9wcztcbiAgICB2YXIgX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KENvbnRleHQpLFxuICAgICAgY29udGV4dE1vdGlvbiA9IF9SZWFjdCR1c2VDb250ZXh0Lm1vdGlvbjtcbiAgICB2YXIgc3VwcG9ydE1vdGlvbiA9IGlzU3VwcG9ydFRyYW5zaXRpb24ocHJvcHMsIGNvbnRleHRNb3Rpb24pO1xuXG4gICAgLy8gUmVmIHRvIHRoZSByZWFjdCBub2RlLCBpdCBtYXkgYmUgYSBIVE1MRWxlbWVudFxuICAgIHZhciBub2RlUmVmID0gdXNlUmVmKCk7XG4gICAgLy8gUmVmIHRvIHRoZSBkb20gd3JhcHBlciBpbiBjYXNlIHJlZiBjYW4gbm90IHBhc3MgdG8gSFRNTEVsZW1lbnRcbiAgICB2YXIgd3JhcHBlck5vZGVSZWYgPSB1c2VSZWYoKTtcbiAgICBmdW5jdGlvbiBnZXREb21FbGVtZW50KCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gSGVyZSB3ZSdyZSBhdm9pZGluZyBjYWxsIGZvciBmaW5kRE9NTm9kZSBzaW5jZSBpdCdzIGRlcHJlY2F0ZWRcbiAgICAgICAgLy8gaW4gc3RyaWN0IG1vZGUuIFdlJ3JlIGNhbGxpbmcgaXQgb25seSB3aGVuIG5vZGUgcmVmIGlzIG5vdFxuICAgICAgICAvLyBhbiBpbnN0YW5jZSBvZiBET00gSFRNTEVsZW1lbnQuIE90aGVyd2lzZSB1c2VcbiAgICAgICAgLy8gZmluZERPTU5vZGUgYXMgYSBmaW5hbCByZXNvcnRcbiAgICAgICAgcmV0dXJuIG5vZGVSZWYuY3VycmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID8gbm9kZVJlZi5jdXJyZW50IDogZmluZERPTU5vZGUod3JhcHBlck5vZGVSZWYuY3VycmVudCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIE9ubHkgaGFwcGVuIHdoZW4gYG1vdGlvbkRlYWRsaW5lYCB0cmlnZ2VyIGJ1dCBlbGVtZW50IHJlbW92ZWQuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgX3VzZVN0YXR1cyA9IHVzZVN0YXR1cyhzdXBwb3J0TW90aW9uLCB2aXNpYmxlLCBnZXREb21FbGVtZW50LCBwcm9wcyksXG4gICAgICBfdXNlU3RhdHVzMiA9IF9zbGljZWRUb0FycmF5KF91c2VTdGF0dXMsIDQpLFxuICAgICAgc3RhdHVzID0gX3VzZVN0YXR1czJbMF0sXG4gICAgICBzdGF0dXNTdGVwID0gX3VzZVN0YXR1czJbMV0sXG4gICAgICBzdGF0dXNTdHlsZSA9IF91c2VTdGF0dXMyWzJdLFxuICAgICAgbWVyZ2VkVmlzaWJsZSA9IF91c2VTdGF0dXMyWzNdO1xuXG4gICAgLy8gUmVjb3JkIHdoZXRoZXIgY29udGVudCBoYXMgcmVuZGVyZWRcbiAgICAvLyBXaWxsIHJldHVybiBudWxsIGZvciB1bi1yZW5kZXJlZCBldmVuIHdoZW4gYHJlbW92ZU9uTGVhdmU9e2ZhbHNlfWBcbiAgICB2YXIgcmVuZGVyZWRSZWYgPSBSZWFjdC51c2VSZWYobWVyZ2VkVmlzaWJsZSk7XG4gICAgaWYgKG1lcmdlZFZpc2libGUpIHtcbiAgICAgIHJlbmRlcmVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT0gUmVmcyA9PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIHNldE5vZGVSZWYgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAobm9kZSkge1xuICAgICAgbm9kZVJlZi5jdXJyZW50ID0gbm9kZTtcbiAgICAgIGZpbGxSZWYocmVmLCBub2RlKTtcbiAgICB9LCBbcmVmXSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBtb3Rpb25DaGlsZHJlbjtcbiAgICB2YXIgbWVyZ2VkUHJvcHMgPSBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGV2ZW50UHJvcHMpLCB7fSwge1xuICAgICAgdmlzaWJsZTogdmlzaWJsZVxuICAgIH0pO1xuICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgIC8vIE5vIGNoaWxkcmVuXG4gICAgICBtb3Rpb25DaGlsZHJlbiA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IFNUQVRVU19OT05FKSB7XG4gICAgICAvLyBTdGFibGUgY2hpbGRyZW5cbiAgICAgIGlmIChtZXJnZWRWaXNpYmxlKSB7XG4gICAgICAgIG1vdGlvbkNoaWxkcmVuID0gY2hpbGRyZW4oX29iamVjdFNwcmVhZCh7fSwgbWVyZ2VkUHJvcHMpLCBzZXROb2RlUmVmKTtcbiAgICAgIH0gZWxzZSBpZiAoIXJlbW92ZU9uTGVhdmUgJiYgcmVuZGVyZWRSZWYuY3VycmVudCAmJiBsZWF2ZWRDbGFzc05hbWUpIHtcbiAgICAgICAgbW90aW9uQ2hpbGRyZW4gPSBjaGlsZHJlbihfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIG1lcmdlZFByb3BzKSwge30sIHtcbiAgICAgICAgICBjbGFzc05hbWU6IGxlYXZlZENsYXNzTmFtZVxuICAgICAgICB9KSwgc2V0Tm9kZVJlZik7XG4gICAgICB9IGVsc2UgaWYgKGZvcmNlUmVuZGVyIHx8ICFyZW1vdmVPbkxlYXZlICYmICFsZWF2ZWRDbGFzc05hbWUpIHtcbiAgICAgICAgbW90aW9uQ2hpbGRyZW4gPSBjaGlsZHJlbihfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIG1lcmdlZFByb3BzKSwge30sIHtcbiAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgZGlzcGxheTogJ25vbmUnXG4gICAgICAgICAgfVxuICAgICAgICB9KSwgc2V0Tm9kZVJlZik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtb3Rpb25DaGlsZHJlbiA9IG51bGw7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBfY2xhc3NOYW1lcztcbiAgICAgIC8vIEluIG1vdGlvblxuICAgICAgdmFyIHN0YXR1c1N1ZmZpeDtcbiAgICAgIGlmIChzdGF0dXNTdGVwID09PSBTVEVQX1BSRVBBUkUpIHtcbiAgICAgICAgc3RhdHVzU3VmZml4ID0gJ3ByZXBhcmUnO1xuICAgICAgfSBlbHNlIGlmIChpc0FjdGl2ZShzdGF0dXNTdGVwKSkge1xuICAgICAgICBzdGF0dXNTdWZmaXggPSAnYWN0aXZlJztcbiAgICAgIH0gZWxzZSBpZiAoc3RhdHVzU3RlcCA9PT0gU1RFUF9TVEFSVCkge1xuICAgICAgICBzdGF0dXNTdWZmaXggPSAnc3RhcnQnO1xuICAgICAgfVxuICAgICAgdmFyIG1vdGlvbkNscyA9IGdldFRyYW5zaXRpb25OYW1lKG1vdGlvbk5hbWUsIFwiXCIuY29uY2F0KHN0YXR1cywgXCItXCIpLmNvbmNhdChzdGF0dXNTdWZmaXgpKTtcbiAgICAgIG1vdGlvbkNoaWxkcmVuID0gY2hpbGRyZW4oX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBtZXJnZWRQcm9wcyksIHt9LCB7XG4gICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyhnZXRUcmFuc2l0aW9uTmFtZShtb3Rpb25OYW1lLCBzdGF0dXMpLCAoX2NsYXNzTmFtZXMgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9jbGFzc05hbWVzLCBtb3Rpb25DbHMsIG1vdGlvbkNscyAmJiBzdGF0dXNTdWZmaXgpLCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIG1vdGlvbk5hbWUsIHR5cGVvZiBtb3Rpb25OYW1lID09PSAnc3RyaW5nJyksIF9jbGFzc05hbWVzKSksXG4gICAgICAgIHN0eWxlOiBzdGF0dXNTdHlsZVxuICAgICAgfSksIHNldE5vZGVSZWYpO1xuICAgIH1cblxuICAgIC8vIEF1dG8gaW5qZWN0IHJlZiBpZiBjaGlsZCBub2RlIG5vdCBoYXZlIGByZWZgIHByb3BzXG4gICAgaWYgKCAvKiNfX1BVUkVfXyovUmVhY3QuaXNWYWxpZEVsZW1lbnQobW90aW9uQ2hpbGRyZW4pICYmIHN1cHBvcnRSZWYobW90aW9uQ2hpbGRyZW4pKSB7XG4gICAgICB2YXIgX3JlZiA9IG1vdGlvbkNoaWxkcmVuLFxuICAgICAgICBvcmlnaW5Ob2RlUmVmID0gX3JlZi5yZWY7XG4gICAgICBpZiAoIW9yaWdpbk5vZGVSZWYpIHtcbiAgICAgICAgbW90aW9uQ2hpbGRyZW4gPSAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KG1vdGlvbkNoaWxkcmVuLCB7XG4gICAgICAgICAgcmVmOiBzZXROb2RlUmVmXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9tV3JhcHBlciwge1xuICAgICAgcmVmOiB3cmFwcGVyTm9kZVJlZlxuICAgIH0sIG1vdGlvbkNoaWxkcmVuKTtcbiAgfSk7XG4gIENTU01vdGlvbi5kaXNwbGF5TmFtZSA9ICdDU1NNb3Rpb24nO1xuICByZXR1cm4gQ1NTTW90aW9uO1xufVxuZXhwb3J0IGRlZmF1bHQgZ2VuQ1NTTW90aW9uKHN1cHBvcnRUcmFuc2l0aW9uKTsiLCJpbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuZXhwb3J0IHZhciBTVEFUVVNfQUREID0gJ2FkZCc7XG5leHBvcnQgdmFyIFNUQVRVU19LRUVQID0gJ2tlZXAnO1xuZXhwb3J0IHZhciBTVEFUVVNfUkVNT1ZFID0gJ3JlbW92ZSc7XG5leHBvcnQgdmFyIFNUQVRVU19SRU1PVkVEID0gJ3JlbW92ZWQnO1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBLZXlUb09iamVjdChrZXkpIHtcbiAgdmFyIGtleU9iajtcbiAgaWYgKGtleSAmJiBfdHlwZW9mKGtleSkgPT09ICdvYmplY3QnICYmICdrZXknIGluIGtleSkge1xuICAgIGtleU9iaiA9IGtleTtcbiAgfSBlbHNlIHtcbiAgICBrZXlPYmogPSB7XG4gICAgICBrZXk6IGtleVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwga2V5T2JqKSwge30sIHtcbiAgICBrZXk6IFN0cmluZyhrZXlPYmoua2V5KVxuICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUtleXMoKSB7XG4gIHZhciBrZXlzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbXTtcbiAgcmV0dXJuIGtleXMubWFwKHdyYXBLZXlUb09iamVjdCk7XG59XG5leHBvcnQgZnVuY3Rpb24gZGlmZktleXMoKSB7XG4gIHZhciBwcmV2S2V5cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogW107XG4gIHZhciBjdXJyZW50S2V5cyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogW107XG4gIHZhciBsaXN0ID0gW107XG4gIHZhciBjdXJyZW50SW5kZXggPSAwO1xuICB2YXIgY3VycmVudExlbiA9IGN1cnJlbnRLZXlzLmxlbmd0aDtcbiAgdmFyIHByZXZLZXlPYmplY3RzID0gcGFyc2VLZXlzKHByZXZLZXlzKTtcbiAgdmFyIGN1cnJlbnRLZXlPYmplY3RzID0gcGFyc2VLZXlzKGN1cnJlbnRLZXlzKTtcblxuICAvLyBDaGVjayBwcmV2IGtleXMgdG8gaW5zZXJ0IG9yIGtlZXBcbiAgcHJldktleU9iamVjdHMuZm9yRWFjaChmdW5jdGlvbiAoa2V5T2JqKSB7XG4gICAgdmFyIGhpdCA9IGZhbHNlO1xuICAgIGZvciAodmFyIGkgPSBjdXJyZW50SW5kZXg7IGkgPCBjdXJyZW50TGVuOyBpICs9IDEpIHtcbiAgICAgIHZhciBjdXJyZW50S2V5T2JqID0gY3VycmVudEtleU9iamVjdHNbaV07XG4gICAgICBpZiAoY3VycmVudEtleU9iai5rZXkgPT09IGtleU9iai5rZXkpIHtcbiAgICAgICAgLy8gTmV3IGFkZGVkIGtleXMgc2hvdWxkIGFkZCBiZWZvcmUgY3VycmVudCBrZXlcbiAgICAgICAgaWYgKGN1cnJlbnRJbmRleCA8IGkpIHtcbiAgICAgICAgICBsaXN0ID0gbGlzdC5jb25jYXQoY3VycmVudEtleU9iamVjdHMuc2xpY2UoY3VycmVudEluZGV4LCBpKS5tYXAoZnVuY3Rpb24gKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgb2JqKSwge30sIHtcbiAgICAgICAgICAgICAgc3RhdHVzOiBTVEFUVVNfQUREXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KSk7XG4gICAgICAgICAgY3VycmVudEluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgICBsaXN0LnB1c2goX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBjdXJyZW50S2V5T2JqKSwge30sIHtcbiAgICAgICAgICBzdGF0dXM6IFNUQVRVU19LRUVQXG4gICAgICAgIH0pKTtcbiAgICAgICAgY3VycmVudEluZGV4ICs9IDE7XG4gICAgICAgIGhpdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIG5vdCBoaXQsIGl0IG1lYW5zIGtleSBpcyByZW1vdmVkXG4gICAgaWYgKCFoaXQpIHtcbiAgICAgIGxpc3QucHVzaChfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGtleU9iaiksIHt9LCB7XG4gICAgICAgIHN0YXR1czogU1RBVFVTX1JFTU9WRVxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQWRkIHJlc3QgdG8gdGhlIGxpc3RcbiAgaWYgKGN1cnJlbnRJbmRleCA8IGN1cnJlbnRMZW4pIHtcbiAgICBsaXN0ID0gbGlzdC5jb25jYXQoY3VycmVudEtleU9iamVjdHMuc2xpY2UoY3VycmVudEluZGV4KS5tYXAoZnVuY3Rpb24gKG9iaikge1xuICAgICAgcmV0dXJuIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgb2JqKSwge30sIHtcbiAgICAgICAgc3RhdHVzOiBTVEFUVVNfQUREXG4gICAgICB9KTtcbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2Ugc2FtZSBrZXkgd2hlbiBpdCByZW1vdmUgYW5kIGFkZCBhZ2FpbjpcbiAgICogICAgWzEgLSBhZGQsIDIgLSBrZWVwLCAxIC0gcmVtb3ZlXSAtPiBbMSAtIGtlZXAsIDIgLSBrZWVwXVxuICAgKi9cbiAgdmFyIGtleXMgPSB7fTtcbiAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgdmFyIGtleSA9IF9yZWYua2V5O1xuICAgIGtleXNba2V5XSA9IChrZXlzW2tleV0gfHwgMCkgKyAxO1xuICB9KTtcbiAgdmFyIGR1cGxpY2F0ZWRLZXlzID0gT2JqZWN0LmtleXMoa2V5cykuZmlsdGVyKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4ga2V5c1trZXldID4gMTtcbiAgfSk7XG4gIGR1cGxpY2F0ZWRLZXlzLmZvckVhY2goZnVuY3Rpb24gKG1hdGNoS2V5KSB7XG4gICAgLy8gUmVtb3ZlIGBTVEFUVVNfUkVNT1ZFYCBub2RlLlxuICAgIGxpc3QgPSBsaXN0LmZpbHRlcihmdW5jdGlvbiAoX3JlZjIpIHtcbiAgICAgIHZhciBrZXkgPSBfcmVmMi5rZXksXG4gICAgICAgIHN0YXR1cyA9IF9yZWYyLnN0YXR1cztcbiAgICAgIHJldHVybiBrZXkgIT09IG1hdGNoS2V5IHx8IHN0YXR1cyAhPT0gU1RBVFVTX1JFTU9WRTtcbiAgICB9KTtcblxuICAgIC8vIFVwZGF0ZSBgU1RBVFVTX0FERGAgdG8gYFNUQVRVU19LRUVQYFxuICAgIGxpc3QuZm9yRWFjaChmdW5jdGlvbiAobm9kZSkge1xuICAgICAgaWYgKG5vZGUua2V5ID09PSBtYXRjaEtleSkge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgbm9kZS5zdGF0dXMgPSBTVEFUVVNfS0VFUDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBsaXN0O1xufSIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX2NsYXNzQ2FsbENoZWNrIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jbGFzc0NhbGxDaGVja1wiO1xuaW1wb3J0IF9jcmVhdGVDbGFzcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlQ2xhc3NcIjtcbmltcG9ydCBfYXNzZXJ0VGhpc0luaXRpYWxpemVkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIjtcbmltcG9ydCBfaW5oZXJpdHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzXCI7XG5pbXBvcnQgX2NyZWF0ZVN1cGVyIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVTdXBlclwiO1xuaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJjb21wb25lbnRcIiwgXCJjaGlsZHJlblwiLCBcIm9uVmlzaWJsZUNoYW5nZWRcIiwgXCJvbkFsbFJlbW92ZWRcIl0sXG4gIF9leGNsdWRlZDIgPSBbXCJzdGF0dXNcIl07XG4vKiBlc2xpbnQgcmVhY3QvcHJvcC10eXBlczogMCAqL1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE9yaWdpbkNTU01vdGlvbiBmcm9tIFwiLi9DU1NNb3Rpb25cIjtcbmltcG9ydCB7IHN1cHBvcnRUcmFuc2l0aW9uIH0gZnJvbSBcIi4vdXRpbC9tb3Rpb25cIjtcbmltcG9ydCB7IFNUQVRVU19BREQsIFNUQVRVU19LRUVQLCBTVEFUVVNfUkVNT1ZFLCBTVEFUVVNfUkVNT1ZFRCwgZGlmZktleXMsIHBhcnNlS2V5cyB9IGZyb20gXCIuL3V0aWwvZGlmZlwiO1xudmFyIE1PVElPTl9QUk9QX05BTUVTID0gWydldmVudFByb3BzJywgJ3Zpc2libGUnLCAnY2hpbGRyZW4nLCAnbW90aW9uTmFtZScsICdtb3Rpb25BcHBlYXInLCAnbW90aW9uRW50ZXInLCAnbW90aW9uTGVhdmUnLCAnbW90aW9uTGVhdmVJbW1lZGlhdGVseScsICdtb3Rpb25EZWFkbGluZScsICdyZW1vdmVPbkxlYXZlJywgJ2xlYXZlZENsYXNzTmFtZScsICdvbkFwcGVhclN0YXJ0JywgJ29uQXBwZWFyQWN0aXZlJywgJ29uQXBwZWFyRW5kJywgJ29uRW50ZXJTdGFydCcsICdvbkVudGVyQWN0aXZlJywgJ29uRW50ZXJFbmQnLCAnb25MZWF2ZVN0YXJ0JywgJ29uTGVhdmVBY3RpdmUnLCAnb25MZWF2ZUVuZCddO1xuLyoqXG4gKiBHZW5lcmF0ZSBhIENTU01vdGlvbkxpc3QgY29tcG9uZW50IHdpdGggY29uZmlnXG4gKiBAcGFyYW0gdHJhbnNpdGlvblN1cHBvcnQgTm8gbmVlZCBzaW5jZSBDU1NNb3Rpb25MaXN0IG5vIGxvbmdlciBkZXBlbmRzIG9uIHRyYW5zaXRpb24gc3VwcG9ydFxuICogQHBhcmFtIENTU01vdGlvbiBDU1NNb3Rpb24gY29tcG9uZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5DU1NNb3Rpb25MaXN0KHRyYW5zaXRpb25TdXBwb3J0KSB7XG4gIHZhciBDU1NNb3Rpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IE9yaWdpbkNTU01vdGlvbjtcbiAgdmFyIENTU01vdGlvbkxpc3QgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQ1NTTW90aW9uTGlzdCwgX1JlYWN0JENvbXBvbmVudCk7XG4gICAgdmFyIF9zdXBlciA9IF9jcmVhdGVTdXBlcihDU1NNb3Rpb25MaXN0KTtcbiAgICBmdW5jdGlvbiBDU1NNb3Rpb25MaXN0KCkge1xuICAgICAgdmFyIF90aGlzO1xuICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENTU01vdGlvbkxpc3QpO1xuICAgICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG4gICAgICBfdGhpcyA9IF9zdXBlci5jYWxsLmFwcGx5KF9zdXBlciwgW3RoaXNdLmNvbmNhdChhcmdzKSk7XG4gICAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwic3RhdGVcIiwge1xuICAgICAgICBrZXlFbnRpdGllczogW11cbiAgICAgIH0pO1xuICAgICAgX2RlZmluZVByb3BlcnR5KF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoX3RoaXMpLCBcInJlbW92ZUtleVwiLCBmdW5jdGlvbiAocmVtb3ZlS2V5KSB7XG4gICAgICAgIHZhciBrZXlFbnRpdGllcyA9IF90aGlzLnN0YXRlLmtleUVudGl0aWVzO1xuICAgICAgICB2YXIgbmV4dEtleUVudGl0aWVzID0ga2V5RW50aXRpZXMubWFwKGZ1bmN0aW9uIChlbnRpdHkpIHtcbiAgICAgICAgICBpZiAoZW50aXR5LmtleSAhPT0gcmVtb3ZlS2V5KSByZXR1cm4gZW50aXR5O1xuICAgICAgICAgIHJldHVybiBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGVudGl0eSksIHt9LCB7XG4gICAgICAgICAgICBzdGF0dXM6IFNUQVRVU19SRU1PVkVEXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAga2V5RW50aXRpZXM6IG5leHRLZXlFbnRpdGllc1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5leHRLZXlFbnRpdGllcy5maWx0ZXIoZnVuY3Rpb24gKF9yZWYpIHtcbiAgICAgICAgICB2YXIgc3RhdHVzID0gX3JlZi5zdGF0dXM7XG4gICAgICAgICAgcmV0dXJuIHN0YXR1cyAhPT0gU1RBVFVTX1JFTU9WRUQ7XG4gICAgICAgIH0pLmxlbmd0aDtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIF90aGlzO1xuICAgIH1cbiAgICBfY3JlYXRlQ2xhc3MoQ1NTTW90aW9uTGlzdCwgW3tcbiAgICAgIGtleTogXCJyZW5kZXJcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuICAgICAgICB2YXIga2V5RW50aXRpZXMgPSB0aGlzLnN0YXRlLmtleUVudGl0aWVzO1xuICAgICAgICB2YXIgX3RoaXMkcHJvcHMgPSB0aGlzLnByb3BzLFxuICAgICAgICAgIGNvbXBvbmVudCA9IF90aGlzJHByb3BzLmNvbXBvbmVudCxcbiAgICAgICAgICBjaGlsZHJlbiA9IF90aGlzJHByb3BzLmNoaWxkcmVuLFxuICAgICAgICAgIF9vblZpc2libGVDaGFuZ2VkID0gX3RoaXMkcHJvcHMub25WaXNpYmxlQ2hhbmdlZCxcbiAgICAgICAgICBvbkFsbFJlbW92ZWQgPSBfdGhpcyRwcm9wcy5vbkFsbFJlbW92ZWQsXG4gICAgICAgICAgcmVzdFByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKF90aGlzJHByb3BzLCBfZXhjbHVkZWQpO1xuICAgICAgICB2YXIgQ29tcG9uZW50ID0gY29tcG9uZW50IHx8IFJlYWN0LkZyYWdtZW50O1xuICAgICAgICB2YXIgbW90aW9uUHJvcHMgPSB7fTtcbiAgICAgICAgTU9USU9OX1BST1BfTkFNRVMuZm9yRWFjaChmdW5jdGlvbiAocHJvcCkge1xuICAgICAgICAgIG1vdGlvblByb3BzW3Byb3BdID0gcmVzdFByb3BzW3Byb3BdO1xuICAgICAgICAgIGRlbGV0ZSByZXN0UHJvcHNbcHJvcF07XG4gICAgICAgIH0pO1xuICAgICAgICBkZWxldGUgcmVzdFByb3BzLmtleXM7XG4gICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDb21wb25lbnQsIHJlc3RQcm9wcywga2V5RW50aXRpZXMubWFwKGZ1bmN0aW9uIChfcmVmMikge1xuICAgICAgICAgIHZhciBzdGF0dXMgPSBfcmVmMi5zdGF0dXMsXG4gICAgICAgICAgICBldmVudFByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKF9yZWYyLCBfZXhjbHVkZWQyKTtcbiAgICAgICAgICB2YXIgdmlzaWJsZSA9IHN0YXR1cyA9PT0gU1RBVFVTX0FERCB8fCBzdGF0dXMgPT09IFNUQVRVU19LRUVQO1xuICAgICAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDU1NNb3Rpb24sIF9leHRlbmRzKHt9LCBtb3Rpb25Qcm9wcywge1xuICAgICAgICAgICAga2V5OiBldmVudFByb3BzLmtleSxcbiAgICAgICAgICAgIHZpc2libGU6IHZpc2libGUsXG4gICAgICAgICAgICBldmVudFByb3BzOiBldmVudFByb3BzLFxuICAgICAgICAgICAgb25WaXNpYmxlQ2hhbmdlZDogZnVuY3Rpb24gb25WaXNpYmxlQ2hhbmdlZChjaGFuZ2VkVmlzaWJsZSkge1xuICAgICAgICAgICAgICBfb25WaXNpYmxlQ2hhbmdlZCA9PT0gbnVsbCB8fCBfb25WaXNpYmxlQ2hhbmdlZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX29uVmlzaWJsZUNoYW5nZWQoY2hhbmdlZFZpc2libGUsIHtcbiAgICAgICAgICAgICAgICBrZXk6IGV2ZW50UHJvcHMua2V5XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAoIWNoYW5nZWRWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlc3RLZXlzQ291bnQgPSBfdGhpczIucmVtb3ZlS2V5KGV2ZW50UHJvcHMua2V5KTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdEtleXNDb3VudCA9PT0gMCAmJiBvbkFsbFJlbW92ZWQpIHtcbiAgICAgICAgICAgICAgICAgIG9uQWxsUmVtb3ZlZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLCBjaGlsZHJlbik7XG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICB9XSwgW3tcbiAgICAgIGtleTogXCJnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHNcIixcbiAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMoX3JlZjMsIF9yZWY0KSB7XG4gICAgICAgIHZhciBrZXlzID0gX3JlZjMua2V5cztcbiAgICAgICAgdmFyIGtleUVudGl0aWVzID0gX3JlZjQua2V5RW50aXRpZXM7XG4gICAgICAgIHZhciBwYXJzZWRLZXlPYmplY3RzID0gcGFyc2VLZXlzKGtleXMpO1xuICAgICAgICB2YXIgbWl4ZWRLZXlFbnRpdGllcyA9IGRpZmZLZXlzKGtleUVudGl0aWVzLCBwYXJzZWRLZXlPYmplY3RzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXlFbnRpdGllczogbWl4ZWRLZXlFbnRpdGllcy5maWx0ZXIoZnVuY3Rpb24gKGVudGl0eSkge1xuICAgICAgICAgICAgdmFyIHByZXZFbnRpdHkgPSBrZXlFbnRpdGllcy5maW5kKGZ1bmN0aW9uIChfcmVmNSkge1xuICAgICAgICAgICAgICB2YXIga2V5ID0gX3JlZjUua2V5O1xuICAgICAgICAgICAgICByZXR1cm4gZW50aXR5LmtleSA9PT0ga2V5O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSBpZiBhbHJlYWR5IG1hcmsgYXMgcmVtb3ZlZFxuICAgICAgICAgICAgaWYgKHByZXZFbnRpdHkgJiYgcHJldkVudGl0eS5zdGF0dXMgPT09IFNUQVRVU19SRU1PVkVEICYmIGVudGl0eS5zdGF0dXMgPT09IFNUQVRVU19SRU1PVkUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSlcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gWm9tYmllSjogUmV0dXJuIHRoZSBjb3VudCBvZiByZXN0IGtleXMuIEl0J3Mgc2FmZSB0byByZWZhY3RvciBpZiBuZWVkIG1vcmUgaW5mby5cbiAgICB9XSk7XG4gICAgcmV0dXJuIENTU01vdGlvbkxpc3Q7XG4gIH0oUmVhY3QuQ29tcG9uZW50KTtcbiAgX2RlZmluZVByb3BlcnR5KENTU01vdGlvbkxpc3QsIFwiZGVmYXVsdFByb3BzXCIsIHtcbiAgICBjb21wb25lbnQ6ICdkaXYnXG4gIH0pO1xuICByZXR1cm4gQ1NTTW90aW9uTGlzdDtcbn1cbmV4cG9ydCBkZWZhdWx0IGdlbkNTU01vdGlvbkxpc3Qoc3VwcG9ydFRyYW5zaXRpb24pOyIsImltcG9ydCBDU1NNb3Rpb24gZnJvbSBcIi4vQ1NTTW90aW9uXCI7XG5pbXBvcnQgQ1NTTW90aW9uTGlzdCBmcm9tIFwiLi9DU1NNb3Rpb25MaXN0XCI7XG5leHBvcnQgeyBkZWZhdWx0IGFzIFByb3ZpZGVyIH0gZnJvbSBcIi4vY29udGV4dFwiO1xuZXhwb3J0IHsgQ1NTTW90aW9uTGlzdCB9O1xuZXhwb3J0IGRlZmF1bHQgQ1NTTW90aW9uOyIsImltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXJyb3cocHJvcHMpIHtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBhbGlnbiA9IHByb3BzLmFsaWduLFxuICAgIGFycm93ID0gcHJvcHMuYXJyb3csXG4gICAgYXJyb3dQb3MgPSBwcm9wcy5hcnJvd1BvcztcbiAgdmFyIF9yZWYgPSBhcnJvdyB8fCB7fSxcbiAgICBjbGFzc05hbWUgPSBfcmVmLmNsYXNzTmFtZSxcbiAgICBjb250ZW50ID0gX3JlZi5jb250ZW50O1xuICB2YXIgX2Fycm93UG9zJHggPSBhcnJvd1Bvcy54LFxuICAgIHggPSBfYXJyb3dQb3MkeCA9PT0gdm9pZCAwID8gMCA6IF9hcnJvd1BvcyR4LFxuICAgIF9hcnJvd1BvcyR5ID0gYXJyb3dQb3MueSxcbiAgICB5ID0gX2Fycm93UG9zJHkgPT09IHZvaWQgMCA/IDAgOiBfYXJyb3dQb3MkeTtcbiAgdmFyIGFycm93UmVmID0gUmVhY3QudXNlUmVmKCk7XG5cbiAgLy8gU2tpcCBpZiBubyBhbGlnblxuICBpZiAoIWFsaWduIHx8ICFhbGlnbi5wb2ludHMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2YXIgYWxpZ25TdHlsZSA9IHtcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJ1xuICB9O1xuXG4gIC8vIFNraXAgaWYgbm8gbmVlZCB0byBhbGlnblxuICBpZiAoYWxpZ24uYXV0b0Fycm93ICE9PSBmYWxzZSkge1xuICAgIHZhciBwb3B1cFBvaW50cyA9IGFsaWduLnBvaW50c1swXTtcbiAgICB2YXIgdGFyZ2V0UG9pbnRzID0gYWxpZ24ucG9pbnRzWzFdO1xuICAgIHZhciBwb3B1cFRCID0gcG9wdXBQb2ludHNbMF07XG4gICAgdmFyIHBvcHVwTFIgPSBwb3B1cFBvaW50c1sxXTtcbiAgICB2YXIgdGFyZ2V0VEIgPSB0YXJnZXRQb2ludHNbMF07XG4gICAgdmFyIHRhcmdldExSID0gdGFyZ2V0UG9pbnRzWzFdO1xuXG4gICAgLy8gVG9wICYgQm90dG9tXG4gICAgaWYgKHBvcHVwVEIgPT09IHRhcmdldFRCIHx8ICFbJ3QnLCAnYiddLmluY2x1ZGVzKHBvcHVwVEIpKSB7XG4gICAgICBhbGlnblN0eWxlLnRvcCA9IHk7XG4gICAgfSBlbHNlIGlmIChwb3B1cFRCID09PSAndCcpIHtcbiAgICAgIGFsaWduU3R5bGUudG9wID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxpZ25TdHlsZS5ib3R0b20gPSAwO1xuICAgIH1cblxuICAgIC8vIExlZnQgJiBSaWdodFxuICAgIGlmIChwb3B1cExSID09PSB0YXJnZXRMUiB8fCAhWydsJywgJ3InXS5pbmNsdWRlcyhwb3B1cExSKSkge1xuICAgICAgYWxpZ25TdHlsZS5sZWZ0ID0geDtcbiAgICB9IGVsc2UgaWYgKHBvcHVwTFIgPT09ICdsJykge1xuICAgICAgYWxpZ25TdHlsZS5sZWZ0ID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxpZ25TdHlsZS5yaWdodCA9IDA7XG4gICAgfVxuICB9XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgcmVmOiBhcnJvd1JlZixcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMoXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1hcnJvd1wiKSwgY2xhc3NOYW1lKSxcbiAgICBzdHlsZTogYWxpZ25TdHlsZVxuICB9LCBjb250ZW50KTtcbn0iLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IENTU01vdGlvbiBmcm9tICdyYy1tb3Rpb24nO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTWFzayhwcm9wcykge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIG9wZW4gPSBwcm9wcy5vcGVuLFxuICAgIHpJbmRleCA9IHByb3BzLnpJbmRleCxcbiAgICBtYXNrID0gcHJvcHMubWFzayxcbiAgICBtb3Rpb24gPSBwcm9wcy5tb3Rpb247XG4gIGlmICghbWFzaykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDU1NNb3Rpb24sIF9leHRlbmRzKHt9LCBtb3Rpb24sIHtcbiAgICBtb3Rpb25BcHBlYXI6IHRydWUsXG4gICAgdmlzaWJsZTogb3BlbixcbiAgICByZW1vdmVPbkxlYXZlOiB0cnVlXG4gIH0pLCBmdW5jdGlvbiAoX3JlZikge1xuICAgIHZhciBjbGFzc05hbWUgPSBfcmVmLmNsYXNzTmFtZTtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgc3R5bGU6IHtcbiAgICAgICAgekluZGV4OiB6SW5kZXhcbiAgICAgIH0sXG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMoXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1tYXNrXCIpLCBjbGFzc05hbWUpXG4gICAgfSk7XG4gIH0pO1xufSIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbnZhciBQb3B1cENvbnRlbnQgPSAvKiNfX1BVUkVfXyovUmVhY3QubWVtbyhmdW5jdGlvbiAoX3JlZikge1xuICB2YXIgY2hpbGRyZW4gPSBfcmVmLmNoaWxkcmVuO1xuICByZXR1cm4gY2hpbGRyZW47XG59LCBmdW5jdGlvbiAoXywgbmV4dCkge1xuICByZXR1cm4gbmV4dC5jYWNoZTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgUG9wdXBDb250ZW50LmRpc3BsYXlOYW1lID0gJ1BvcHVwQ29udGVudCc7XG59XG5leHBvcnQgZGVmYXVsdCBQb3B1cENvbnRlbnQ7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBDU1NNb3Rpb24gZnJvbSAncmMtbW90aW9uJztcbmltcG9ydCBSZXNpemVPYnNlcnZlciBmcm9tICdyYy1yZXNpemUtb2JzZXJ2ZXInO1xuaW1wb3J0IHVzZUxheW91dEVmZmVjdCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCB7IGNvbXBvc2VSZWYgfSBmcm9tIFwicmMtdXRpbC9lcy9yZWZcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBBcnJvdyBmcm9tIFwiLi9BcnJvd1wiO1xuaW1wb3J0IE1hc2sgZnJvbSBcIi4vTWFza1wiO1xuaW1wb3J0IFBvcHVwQ29udGVudCBmcm9tIFwiLi9Qb3B1cENvbnRlbnRcIjtcbnZhciBQb3B1cCA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIChwcm9wcywgcmVmKSB7XG4gIHZhciBwb3B1cCA9IHByb3BzLnBvcHVwLFxuICAgIGNsYXNzTmFtZSA9IHByb3BzLmNsYXNzTmFtZSxcbiAgICBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICB0YXJnZXQgPSBwcm9wcy50YXJnZXQsXG4gICAgX29uVmlzaWJsZUNoYW5nZWQgPSBwcm9wcy5vblZpc2libGVDaGFuZ2VkLFxuICAgIG9wZW4gPSBwcm9wcy5vcGVuLFxuICAgIGtlZXBEb20gPSBwcm9wcy5rZWVwRG9tLFxuICAgIG9uQ2xpY2sgPSBwcm9wcy5vbkNsaWNrLFxuICAgIG1hc2sgPSBwcm9wcy5tYXNrLFxuICAgIGFycm93ID0gcHJvcHMuYXJyb3csXG4gICAgYXJyb3dQb3MgPSBwcm9wcy5hcnJvd1BvcyxcbiAgICBhbGlnbiA9IHByb3BzLmFsaWduLFxuICAgIG1vdGlvbiA9IHByb3BzLm1vdGlvbixcbiAgICBtYXNrTW90aW9uID0gcHJvcHMubWFza01vdGlvbixcbiAgICBmb3JjZVJlbmRlciA9IHByb3BzLmZvcmNlUmVuZGVyLFxuICAgIGdldFBvcHVwQ29udGFpbmVyID0gcHJvcHMuZ2V0UG9wdXBDb250YWluZXIsXG4gICAgYXV0b0Rlc3Ryb3kgPSBwcm9wcy5hdXRvRGVzdHJveSxcbiAgICBQb3J0YWwgPSBwcm9wcy5wb3J0YWwsXG4gICAgekluZGV4ID0gcHJvcHMuekluZGV4LFxuICAgIG9uTW91c2VFbnRlciA9IHByb3BzLm9uTW91c2VFbnRlcixcbiAgICBvbk1vdXNlTGVhdmUgPSBwcm9wcy5vbk1vdXNlTGVhdmUsXG4gICAgcmVhZHkgPSBwcm9wcy5yZWFkeSxcbiAgICBvZmZzZXRYID0gcHJvcHMub2Zmc2V0WCxcbiAgICBvZmZzZXRZID0gcHJvcHMub2Zmc2V0WSxcbiAgICBvbkFsaWduID0gcHJvcHMub25BbGlnbixcbiAgICBvblByZXBhcmUgPSBwcm9wcy5vblByZXBhcmUsXG4gICAgc3RyZXRjaCA9IHByb3BzLnN0cmV0Y2gsXG4gICAgdGFyZ2V0V2lkdGggPSBwcm9wcy50YXJnZXRXaWR0aCxcbiAgICB0YXJnZXRIZWlnaHQgPSBwcm9wcy50YXJnZXRIZWlnaHQ7XG4gIHZhciBjaGlsZE5vZGUgPSB0eXBlb2YgcG9wdXAgPT09ICdmdW5jdGlvbicgPyBwb3B1cCgpIDogcG9wdXA7XG5cbiAgLy8gV2UgY2FuIG5vdCByZW1vdmUgaG9sZGVyIG9ubHkgd2hlbiBtb3Rpb24gZmluaXNoZWQuXG4gIHZhciBpc05vZGVWaXNpYmxlID0gb3BlbiB8fCBrZWVwRG9tO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09IENvbnRhaW5lciA9PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGdldFBvcHVwQ29udGFpbmVyTmVlZFBhcmFtcyA9IChnZXRQb3B1cENvbnRhaW5lciA9PT0gbnVsbCB8fCBnZXRQb3B1cENvbnRhaW5lciA9PT0gdm9pZCAwID8gdm9pZCAwIDogZ2V0UG9wdXBDb250YWluZXIubGVuZ3RoKSA+IDA7XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZSghZ2V0UG9wdXBDb250YWluZXIgfHwgIWdldFBvcHVwQ29udGFpbmVyTmVlZFBhcmFtcyksXG4gICAgX1JlYWN0JHVzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZSwgMiksXG4gICAgc2hvdyA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgc2V0U2hvdyA9IF9SZWFjdCR1c2VTdGF0ZTJbMV07XG5cbiAgLy8gRGVsYXkgdG8gc2hvdyBzaW5jZSBgZ2V0UG9wdXBDb250YWluZXJgIG5lZWQgdGFyZ2V0IGVsZW1lbnRcbiAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXNob3cgJiYgZ2V0UG9wdXBDb250YWluZXJOZWVkUGFyYW1zICYmIHRhcmdldCkge1xuICAgICAgc2V0U2hvdyh0cnVlKTtcbiAgICB9XG4gIH0sIFtzaG93LCBnZXRQb3B1cENvbnRhaW5lck5lZWRQYXJhbXMsIHRhcmdldF0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgaWYgKCFzaG93KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyA+Pj4+PiBPZmZzZXRcbiAgdmFyIG9mZnNldFN0eWxlID0gcmVhZHkgfHwgIW9wZW4gPyB7XG4gICAgbGVmdDogb2Zmc2V0WCxcbiAgICB0b3A6IG9mZnNldFlcbiAgfSA6IHtcbiAgICBsZWZ0OiAnLTEwMDB2dycsXG4gICAgdG9wOiAnLTEwMDB2aCdcbiAgfTtcblxuICAvLyA+Pj4+PiBNaXNjXG4gIHZhciBtaXNjU3R5bGUgPSB7fTtcbiAgaWYgKHN0cmV0Y2gpIHtcbiAgICBpZiAoc3RyZXRjaC5pbmNsdWRlcygnaGVpZ2h0JykgJiYgdGFyZ2V0SGVpZ2h0KSB7XG4gICAgICBtaXNjU3R5bGUuaGVpZ2h0ID0gdGFyZ2V0SGVpZ2h0O1xuICAgIH0gZWxzZSBpZiAoc3RyZXRjaC5pbmNsdWRlcygnbWluSGVpZ2h0JykgJiYgdGFyZ2V0SGVpZ2h0KSB7XG4gICAgICBtaXNjU3R5bGUubWluSGVpZ2h0ID0gdGFyZ2V0SGVpZ2h0O1xuICAgIH1cbiAgICBpZiAoc3RyZXRjaC5pbmNsdWRlcygnd2lkdGgnKSAmJiB0YXJnZXRXaWR0aCkge1xuICAgICAgbWlzY1N0eWxlLndpZHRoID0gdGFyZ2V0V2lkdGg7XG4gICAgfSBlbHNlIGlmIChzdHJldGNoLmluY2x1ZGVzKCdtaW5XaWR0aCcpICYmIHRhcmdldFdpZHRoKSB7XG4gICAgICBtaXNjU3R5bGUubWluV2lkdGggPSB0YXJnZXRXaWR0aDtcbiAgICB9XG4gIH1cbiAgaWYgKCFvcGVuKSB7XG4gICAgbWlzY1N0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBvcnRhbCwge1xuICAgIG9wZW46IGZvcmNlUmVuZGVyIHx8IGlzTm9kZVZpc2libGUsXG4gICAgZ2V0Q29udGFpbmVyOiBnZXRQb3B1cENvbnRhaW5lciAmJiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gZ2V0UG9wdXBDb250YWluZXIodGFyZ2V0KTtcbiAgICB9LFxuICAgIGF1dG9EZXN0cm95OiBhdXRvRGVzdHJveVxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChNYXNrLCB7XG4gICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgb3Blbjogb3BlbixcbiAgICB6SW5kZXg6IHpJbmRleCxcbiAgICBtYXNrOiBtYXNrLFxuICAgIG1vdGlvbjogbWFza01vdGlvblxuICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUmVzaXplT2JzZXJ2ZXIsIHtcbiAgICBvblJlc2l6ZTogb25BbGlnbixcbiAgICBkaXNhYmxlZDogIW9wZW5cbiAgfSwgZnVuY3Rpb24gKHJlc2l6ZU9ic2VydmVyUmVmKSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KENTU01vdGlvbiwgX2V4dGVuZHMoe1xuICAgICAgbW90aW9uQXBwZWFyOiB0cnVlLFxuICAgICAgbW90aW9uRW50ZXI6IHRydWUsXG4gICAgICBtb3Rpb25MZWF2ZTogdHJ1ZSxcbiAgICAgIHJlbW92ZU9uTGVhdmU6IGZhbHNlLFxuICAgICAgZm9yY2VSZW5kZXI6IGZvcmNlUmVuZGVyLFxuICAgICAgbGVhdmVkQ2xhc3NOYW1lOiBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWhpZGRlblwiKVxuICAgIH0sIG1vdGlvbiwge1xuICAgICAgb25BcHBlYXJQcmVwYXJlOiBvblByZXBhcmUsXG4gICAgICBvbkVudGVyUHJlcGFyZTogb25QcmVwYXJlLFxuICAgICAgdmlzaWJsZTogb3BlbixcbiAgICAgIG9uVmlzaWJsZUNoYW5nZWQ6IGZ1bmN0aW9uIG9uVmlzaWJsZUNoYW5nZWQobmV4dFZpc2libGUpIHtcbiAgICAgICAgdmFyIF9tb3Rpb24kb25WaXNpYmxlQ2hhbjtcbiAgICAgICAgbW90aW9uID09PSBudWxsIHx8IG1vdGlvbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogKF9tb3Rpb24kb25WaXNpYmxlQ2hhbiA9IG1vdGlvbi5vblZpc2libGVDaGFuZ2VkKSA9PT0gbnVsbCB8fCBfbW90aW9uJG9uVmlzaWJsZUNoYW4gPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9tb3Rpb24kb25WaXNpYmxlQ2hhbi5jYWxsKG1vdGlvbiwgbmV4dFZpc2libGUpO1xuICAgICAgICBfb25WaXNpYmxlQ2hhbmdlZChuZXh0VmlzaWJsZSk7XG4gICAgICB9XG4gICAgfSksIGZ1bmN0aW9uIChfcmVmLCBtb3Rpb25SZWYpIHtcbiAgICAgIHZhciBtb3Rpb25DbGFzc05hbWUgPSBfcmVmLmNsYXNzTmFtZSxcbiAgICAgICAgbW90aW9uU3R5bGUgPSBfcmVmLnN0eWxlO1xuICAgICAgdmFyIGNscyA9IGNsYXNzTmFtZXMocHJlZml4Q2xzLCBtb3Rpb25DbGFzc05hbWUsIGNsYXNzTmFtZSk7XG4gICAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgICAgICByZWY6IGNvbXBvc2VSZWYocmVzaXplT2JzZXJ2ZXJSZWYsIHJlZiwgbW90aW9uUmVmKSxcbiAgICAgICAgY2xhc3NOYW1lOiBjbHMsXG4gICAgICAgIHN0eWxlOiBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHtcbiAgICAgICAgICAnLS1hcnJvdy14JzogXCJcIi5jb25jYXQoYXJyb3dQb3MueCB8fCAwLCBcInB4XCIpLFxuICAgICAgICAgICctLWFycm93LXknOiBcIlwiLmNvbmNhdChhcnJvd1Bvcy55IHx8IDAsIFwicHhcIilcbiAgICAgICAgfSwgb2Zmc2V0U3R5bGUpLCBtaXNjU3R5bGUpLCBtb3Rpb25TdHlsZSksIHt9LCB7XG4gICAgICAgICAgYm94U2l6aW5nOiAnYm9yZGVyLWJveCcsXG4gICAgICAgICAgekluZGV4OiB6SW5kZXhcbiAgICAgICAgfSwgc3R5bGUpLFxuICAgICAgICBvbk1vdXNlRW50ZXI6IG9uTW91c2VFbnRlcixcbiAgICAgICAgb25Nb3VzZUxlYXZlOiBvbk1vdXNlTGVhdmUsXG4gICAgICAgIG9uQ2xpY2s6IG9uQ2xpY2tcbiAgICAgIH0sIGFycm93ICYmIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KEFycm93LCB7XG4gICAgICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgICAgICBhcnJvdzogYXJyb3csXG4gICAgICAgIGFycm93UG9zOiBhcnJvd1BvcyxcbiAgICAgICAgYWxpZ246IGFsaWduXG4gICAgICB9KSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUG9wdXBDb250ZW50LCB7XG4gICAgICAgIGNhY2hlOiAhb3BlblxuICAgICAgfSwgY2hpbGROb2RlKSk7XG4gICAgfSk7XG4gIH0pKTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgUG9wdXAuZGlzcGxheU5hbWUgPSAnUG9wdXAnO1xufVxuZXhwb3J0IGRlZmF1bHQgUG9wdXA7IiwiaW1wb3J0IHsgZmlsbFJlZiwgc3VwcG9ydFJlZiwgdXNlQ29tcG9zZVJlZiB9IGZyb20gXCJyYy11dGlsL2VzL3JlZlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xudmFyIFRyaWdnZXJXcmFwcGVyID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgZ2V0VHJpZ2dlckRPTU5vZGUgPSBwcm9wcy5nZXRUcmlnZ2VyRE9NTm9kZTtcbiAgdmFyIGNhblVzZVJlZiA9IHN1cHBvcnRSZWYoY2hpbGRyZW4pO1xuXG4gIC8vIFdoZW4gdXNlIGBnZXRUcmlnZ2VyRE9NTm9kZWAsIHdlIHNob3VsZCBkbyBhZGRpdGlvbmFsIHdvcmsgdG8gZ2V0IHRoZSByZWFsIGRvbVxuICB2YXIgc2V0UmVmID0gUmVhY3QudXNlQ2FsbGJhY2soZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBmaWxsUmVmKHJlZiwgZ2V0VHJpZ2dlckRPTU5vZGUgPyBnZXRUcmlnZ2VyRE9NTm9kZShub2RlKSA6IG5vZGUpO1xuICB9LCBbZ2V0VHJpZ2dlckRPTU5vZGVdKTtcbiAgdmFyIG1lcmdlZFJlZiA9IHVzZUNvbXBvc2VSZWYoc2V0UmVmLCBjaGlsZHJlbi5yZWYpO1xuICByZXR1cm4gY2FuVXNlUmVmID8gLyojX19QVVJFX18qL1JlYWN0LmNsb25lRWxlbWVudChjaGlsZHJlbiwge1xuICAgIHJlZjogbWVyZ2VkUmVmXG4gIH0pIDogY2hpbGRyZW47XG59KTtcbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIFRyaWdnZXJXcmFwcGVyLmRpc3BsYXlOYW1lID0gJ1RyaWdnZXJXcmFwcGVyJztcbn1cbmV4cG9ydCBkZWZhdWx0IFRyaWdnZXJXcmFwcGVyOyIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzXCI7XG52YXIgX2V4Y2x1ZGVkID0gW1wicHJlZml4Q2xzXCIsIFwiY2hpbGRyZW5cIiwgXCJhY3Rpb25cIiwgXCJzaG93QWN0aW9uXCIsIFwiaGlkZUFjdGlvblwiLCBcInBvcHVwVmlzaWJsZVwiLCBcImRlZmF1bHRQb3B1cFZpc2libGVcIiwgXCJvblBvcHVwVmlzaWJsZUNoYW5nZVwiLCBcImFmdGVyUG9wdXBWaXNpYmxlQ2hhbmdlXCIsIFwibW91c2VFbnRlckRlbGF5XCIsIFwibW91c2VMZWF2ZURlbGF5XCIsIFwiZm9jdXNEZWxheVwiLCBcImJsdXJEZWxheVwiLCBcIm1hc2tcIiwgXCJtYXNrQ2xvc2FibGVcIiwgXCJnZXRQb3B1cENvbnRhaW5lclwiLCBcImZvcmNlUmVuZGVyXCIsIFwiYXV0b0Rlc3Ryb3lcIiwgXCJkZXN0cm95UG9wdXBPbkhpZGVcIiwgXCJwb3B1cFwiLCBcInBvcHVwQ2xhc3NOYW1lXCIsIFwicG9wdXBTdHlsZVwiLCBcInBvcHVwUGxhY2VtZW50XCIsIFwiYnVpbHRpblBsYWNlbWVudHNcIiwgXCJwb3B1cEFsaWduXCIsIFwiekluZGV4XCIsIFwic3RyZXRjaFwiLCBcImdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduXCIsIFwiYWxpZ25Qb2ludFwiLCBcIm9uUG9wdXBDbGlja1wiLCBcIm9uUG9wdXBBbGlnblwiLCBcImFycm93XCIsIFwicG9wdXBNb3Rpb25cIiwgXCJtYXNrTW90aW9uXCIsIFwicG9wdXBUcmFuc2l0aW9uTmFtZVwiLCBcInBvcHVwQW5pbWF0aW9uXCIsIFwibWFza1RyYW5zaXRpb25OYW1lXCIsIFwibWFza0FuaW1hdGlvblwiLCBcImNsYXNzTmFtZVwiLCBcImdldFRyaWdnZXJET01Ob2RlXCJdO1xuaW1wb3J0IFBvcnRhbCBmcm9tICdAcmMtY29tcG9uZW50L3BvcnRhbCc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCBSZXNpemVPYnNlcnZlciBmcm9tICdyYy1yZXNpemUtb2JzZXJ2ZXInO1xuaW1wb3J0IHsgaXNET00gfSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vZmluZERPTU5vZGVcIjtcbmltcG9ydCB1c2VFdmVudCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VFdmVudFwiO1xuaW1wb3J0IHVzZUlkIGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUlkXCI7XG5pbXBvcnQgdXNlTGF5b3V0RWZmZWN0IGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUxheW91dEVmZmVjdFwiO1xuaW1wb3J0IGlzTW9iaWxlIGZyb20gXCJyYy11dGlsL2VzL2lzTW9iaWxlXCI7XG5pbXBvcnQgd2FybmluZyBmcm9tIFwicmMtdXRpbC9lcy93YXJuaW5nXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgVHJpZ2dlckNvbnRleHQgZnJvbSBcIi4vY29udGV4dFwiO1xuaW1wb3J0IHVzZUFjdGlvbiBmcm9tIFwiLi9ob29rcy91c2VBY3Rpb25cIjtcbmltcG9ydCB1c2VBbGlnbiBmcm9tIFwiLi9ob29rcy91c2VBbGlnblwiO1xuaW1wb3J0IHVzZVdhdGNoIGZyb20gXCIuL2hvb2tzL3VzZVdhdGNoXCI7XG5pbXBvcnQgUG9wdXAgZnJvbSBcIi4vUG9wdXBcIjtcbmltcG9ydCBUcmlnZ2VyV3JhcHBlciBmcm9tIFwiLi9UcmlnZ2VyV3JhcHBlclwiO1xuaW1wb3J0IHsgZ2V0QWxpZ25Qb3B1cENsYXNzTmFtZSwgZ2V0TW90aW9uLCBnZXRXaW4gfSBmcm9tIFwiLi91dGlsXCI7XG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVUcmlnZ2VyKCkge1xuICB2YXIgUG9ydGFsQ29tcG9uZW50ID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBQb3J0YWw7XG4gIHZhciBUcmlnZ2VyID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgICB2YXIgX3Byb3BzJHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICAgIHByZWZpeENscyA9IF9wcm9wcyRwcmVmaXhDbHMgPT09IHZvaWQgMCA/ICdyYy10cmlnZ2VyLXBvcHVwJyA6IF9wcm9wcyRwcmVmaXhDbHMsXG4gICAgICBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgICAgX3Byb3BzJGFjdGlvbiA9IHByb3BzLmFjdGlvbixcbiAgICAgIGFjdGlvbiA9IF9wcm9wcyRhY3Rpb24gPT09IHZvaWQgMCA/ICdob3ZlcicgOiBfcHJvcHMkYWN0aW9uLFxuICAgICAgc2hvd0FjdGlvbiA9IHByb3BzLnNob3dBY3Rpb24sXG4gICAgICBoaWRlQWN0aW9uID0gcHJvcHMuaGlkZUFjdGlvbixcbiAgICAgIHBvcHVwVmlzaWJsZSA9IHByb3BzLnBvcHVwVmlzaWJsZSxcbiAgICAgIGRlZmF1bHRQb3B1cFZpc2libGUgPSBwcm9wcy5kZWZhdWx0UG9wdXBWaXNpYmxlLFxuICAgICAgb25Qb3B1cFZpc2libGVDaGFuZ2UgPSBwcm9wcy5vblBvcHVwVmlzaWJsZUNoYW5nZSxcbiAgICAgIGFmdGVyUG9wdXBWaXNpYmxlQ2hhbmdlID0gcHJvcHMuYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2UsXG4gICAgICBtb3VzZUVudGVyRGVsYXkgPSBwcm9wcy5tb3VzZUVudGVyRGVsYXksXG4gICAgICBfcHJvcHMkbW91c2VMZWF2ZURlbGEgPSBwcm9wcy5tb3VzZUxlYXZlRGVsYXksXG4gICAgICBtb3VzZUxlYXZlRGVsYXkgPSBfcHJvcHMkbW91c2VMZWF2ZURlbGEgPT09IHZvaWQgMCA/IDAuMSA6IF9wcm9wcyRtb3VzZUxlYXZlRGVsYSxcbiAgICAgIGZvY3VzRGVsYXkgPSBwcm9wcy5mb2N1c0RlbGF5LFxuICAgICAgYmx1ckRlbGF5ID0gcHJvcHMuYmx1ckRlbGF5LFxuICAgICAgbWFzayA9IHByb3BzLm1hc2ssXG4gICAgICBfcHJvcHMkbWFza0Nsb3NhYmxlID0gcHJvcHMubWFza0Nsb3NhYmxlLFxuICAgICAgbWFza0Nsb3NhYmxlID0gX3Byb3BzJG1hc2tDbG9zYWJsZSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRtYXNrQ2xvc2FibGUsXG4gICAgICBnZXRQb3B1cENvbnRhaW5lciA9IHByb3BzLmdldFBvcHVwQ29udGFpbmVyLFxuICAgICAgZm9yY2VSZW5kZXIgPSBwcm9wcy5mb3JjZVJlbmRlcixcbiAgICAgIGF1dG9EZXN0cm95ID0gcHJvcHMuYXV0b0Rlc3Ryb3ksXG4gICAgICBkZXN0cm95UG9wdXBPbkhpZGUgPSBwcm9wcy5kZXN0cm95UG9wdXBPbkhpZGUsXG4gICAgICBwb3B1cCA9IHByb3BzLnBvcHVwLFxuICAgICAgcG9wdXBDbGFzc05hbWUgPSBwcm9wcy5wb3B1cENsYXNzTmFtZSxcbiAgICAgIHBvcHVwU3R5bGUgPSBwcm9wcy5wb3B1cFN0eWxlLFxuICAgICAgcG9wdXBQbGFjZW1lbnQgPSBwcm9wcy5wb3B1cFBsYWNlbWVudCxcbiAgICAgIF9wcm9wcyRidWlsdGluUGxhY2VtZSA9IHByb3BzLmJ1aWx0aW5QbGFjZW1lbnRzLFxuICAgICAgYnVpbHRpblBsYWNlbWVudHMgPSBfcHJvcHMkYnVpbHRpblBsYWNlbWUgPT09IHZvaWQgMCA/IHt9IDogX3Byb3BzJGJ1aWx0aW5QbGFjZW1lLFxuICAgICAgcG9wdXBBbGlnbiA9IHByb3BzLnBvcHVwQWxpZ24sXG4gICAgICB6SW5kZXggPSBwcm9wcy56SW5kZXgsXG4gICAgICBzdHJldGNoID0gcHJvcHMuc3RyZXRjaCxcbiAgICAgIGdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduID0gcHJvcHMuZ2V0UG9wdXBDbGFzc05hbWVGcm9tQWxpZ24sXG4gICAgICBhbGlnblBvaW50ID0gcHJvcHMuYWxpZ25Qb2ludCxcbiAgICAgIG9uUG9wdXBDbGljayA9IHByb3BzLm9uUG9wdXBDbGljayxcbiAgICAgIG9uUG9wdXBBbGlnbiA9IHByb3BzLm9uUG9wdXBBbGlnbixcbiAgICAgIGFycm93ID0gcHJvcHMuYXJyb3csXG4gICAgICBwb3B1cE1vdGlvbiA9IHByb3BzLnBvcHVwTW90aW9uLFxuICAgICAgbWFza01vdGlvbiA9IHByb3BzLm1hc2tNb3Rpb24sXG4gICAgICBwb3B1cFRyYW5zaXRpb25OYW1lID0gcHJvcHMucG9wdXBUcmFuc2l0aW9uTmFtZSxcbiAgICAgIHBvcHVwQW5pbWF0aW9uID0gcHJvcHMucG9wdXBBbmltYXRpb24sXG4gICAgICBtYXNrVHJhbnNpdGlvbk5hbWUgPSBwcm9wcy5tYXNrVHJhbnNpdGlvbk5hbWUsXG4gICAgICBtYXNrQW5pbWF0aW9uID0gcHJvcHMubWFza0FuaW1hdGlvbixcbiAgICAgIGNsYXNzTmFtZSA9IHByb3BzLmNsYXNzTmFtZSxcbiAgICAgIGdldFRyaWdnZXJET01Ob2RlID0gcHJvcHMuZ2V0VHJpZ2dlckRPTU5vZGUsXG4gICAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIF9leGNsdWRlZCk7XG4gICAgdmFyIG1lcmdlZEF1dG9EZXN0cm95ID0gYXV0b0Rlc3Ryb3kgfHwgZGVzdHJveVBvcHVwT25IaWRlIHx8IGZhbHNlO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IE1vYmlsZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUoZmFsc2UpLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZSwgMiksXG4gICAgICBtb2JpbGUgPSBfUmVhY3QkdXNlU3RhdGUyWzBdLFxuICAgICAgc2V0TW9iaWxlID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgc2V0TW9iaWxlKGlzTW9iaWxlKCkpO1xuICAgIH0sIFtdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IENvbnRleHQgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIHN1YlBvcHVwRWxlbWVudHMgPSBSZWFjdC51c2VSZWYoe30pO1xuICAgIHZhciBwYXJlbnRDb250ZXh0ID0gUmVhY3QudXNlQ29udGV4dChUcmlnZ2VyQ29udGV4dCk7XG4gICAgdmFyIGNvbnRleHQgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlZ2lzdGVyU3ViUG9wdXA6IGZ1bmN0aW9uIHJlZ2lzdGVyU3ViUG9wdXAoaWQsIHN1YlBvcHVwRWxlKSB7XG4gICAgICAgICAgc3ViUG9wdXBFbGVtZW50cy5jdXJyZW50W2lkXSA9IHN1YlBvcHVwRWxlO1xuICAgICAgICAgIHBhcmVudENvbnRleHQgPT09IG51bGwgfHwgcGFyZW50Q29udGV4dCA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyZW50Q29udGV4dC5yZWdpc3RlclN1YlBvcHVwKGlkLCBzdWJQb3B1cEVsZSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSwgW3BhcmVudENvbnRleHRdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBQb3B1cCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIGlkID0gdXNlSWQoKTtcbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlMyA9IFJlYWN0LnVzZVN0YXRlKG51bGwpLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlNCA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTMsIDIpLFxuICAgICAgcG9wdXBFbGUgPSBfUmVhY3QkdXNlU3RhdGU0WzBdLFxuICAgICAgc2V0UG9wdXBFbGUgPSBfUmVhY3QkdXNlU3RhdGU0WzFdO1xuICAgIHZhciBzZXRQb3B1cFJlZiA9IHVzZUV2ZW50KGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICBpZiAoaXNET00obm9kZSkgJiYgcG9wdXBFbGUgIT09IG5vZGUpIHtcbiAgICAgICAgc2V0UG9wdXBFbGUobm9kZSk7XG4gICAgICB9XG4gICAgICBwYXJlbnRDb250ZXh0ID09PSBudWxsIHx8IHBhcmVudENvbnRleHQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmVudENvbnRleHQucmVnaXN0ZXJTdWJQb3B1cChpZCwgbm9kZSk7XG4gICAgfSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gVGFyZ2V0ID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFVzZSBzdGF0ZSB0byBjb250cm9sIGhlcmUgc2luY2UgYHVzZVJlZmAgdXBkYXRlIG5vdCB0cmlnZ2VyIHJlbmRlclxuICAgIHZhciBfUmVhY3QkdXNlU3RhdGU1ID0gUmVhY3QudXNlU3RhdGUobnVsbCksXG4gICAgICBfUmVhY3QkdXNlU3RhdGU2ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlNSwgMiksXG4gICAgICB0YXJnZXRFbGUgPSBfUmVhY3QkdXNlU3RhdGU2WzBdLFxuICAgICAgc2V0VGFyZ2V0RWxlID0gX1JlYWN0JHVzZVN0YXRlNlsxXTtcbiAgICB2YXIgc2V0VGFyZ2V0UmVmID0gdXNlRXZlbnQoZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgIGlmIChpc0RPTShub2RlKSAmJiB0YXJnZXRFbGUgIT09IG5vZGUpIHtcbiAgICAgICAgc2V0VGFyZ2V0RWxlKG5vZGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gQ2hpbGRyZW4gPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgY2hpbGQgPSBSZWFjdC5DaGlsZHJlbi5vbmx5KGNoaWxkcmVuKTtcbiAgICB2YXIgb3JpZ2luQ2hpbGRQcm9wcyA9IChjaGlsZCA9PT0gbnVsbCB8fCBjaGlsZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogY2hpbGQucHJvcHMpIHx8IHt9O1xuICAgIHZhciBjbG9uZVByb3BzID0ge307XG4gICAgdmFyIGluUG9wdXBPckNoaWxkID0gdXNlRXZlbnQoZnVuY3Rpb24gKGVsZSkge1xuICAgICAgdmFyIF9jaGlsZERPTSRnZXRSb290Tm9kZSwgX3BvcHVwRWxlJGdldFJvb3ROb2RlO1xuICAgICAgdmFyIGNoaWxkRE9NID0gdGFyZ2V0RWxlO1xuICAgICAgcmV0dXJuIChjaGlsZERPTSA9PT0gbnVsbCB8fCBjaGlsZERPTSA9PT0gdm9pZCAwID8gdm9pZCAwIDogY2hpbGRET00uY29udGFpbnMoZWxlKSkgfHwgKGNoaWxkRE9NID09PSBudWxsIHx8IGNoaWxkRE9NID09PSB2b2lkIDAgPyB2b2lkIDAgOiAoX2NoaWxkRE9NJGdldFJvb3ROb2RlID0gY2hpbGRET00uZ2V0Um9vdE5vZGUoKSkgPT09IG51bGwgfHwgX2NoaWxkRE9NJGdldFJvb3ROb2RlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfY2hpbGRET00kZ2V0Um9vdE5vZGUuaG9zdCkgPT09IGVsZSB8fCBlbGUgPT09IGNoaWxkRE9NIHx8IChwb3B1cEVsZSA9PT0gbnVsbCB8fCBwb3B1cEVsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogcG9wdXBFbGUuY29udGFpbnMoZWxlKSkgfHwgKHBvcHVwRWxlID09PSBudWxsIHx8IHBvcHVwRWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiAoX3BvcHVwRWxlJGdldFJvb3ROb2RlID0gcG9wdXBFbGUuZ2V0Um9vdE5vZGUoKSkgPT09IG51bGwgfHwgX3BvcHVwRWxlJGdldFJvb3ROb2RlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfcG9wdXBFbGUkZ2V0Um9vdE5vZGUuaG9zdCkgPT09IGVsZSB8fCBlbGUgPT09IHBvcHVwRWxlIHx8IE9iamVjdC52YWx1ZXMoc3ViUG9wdXBFbGVtZW50cy5jdXJyZW50KS5zb21lKGZ1bmN0aW9uIChzdWJQb3B1cEVsZSkge1xuICAgICAgICByZXR1cm4gKHN1YlBvcHVwRWxlID09PSBudWxsIHx8IHN1YlBvcHVwRWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBzdWJQb3B1cEVsZS5jb250YWlucyhlbGUpKSB8fCBlbGUgPT09IHN1YlBvcHVwRWxlO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gTW90aW9uID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBtZXJnZVBvcHVwTW90aW9uID0gZ2V0TW90aW9uKHByZWZpeENscywgcG9wdXBNb3Rpb24sIHBvcHVwQW5pbWF0aW9uLCBwb3B1cFRyYW5zaXRpb25OYW1lKTtcbiAgICB2YXIgbWVyZ2VNYXNrTW90aW9uID0gZ2V0TW90aW9uKHByZWZpeENscywgbWFza01vdGlvbiwgbWFza0FuaW1hdGlvbiwgbWFza1RyYW5zaXRpb25OYW1lKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gT3BlbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIF9SZWFjdCR1c2VTdGF0ZTcgPSBSZWFjdC51c2VTdGF0ZShkZWZhdWx0UG9wdXBWaXNpYmxlIHx8IGZhbHNlKSxcbiAgICAgIF9SZWFjdCR1c2VTdGF0ZTggPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGU3LCAyKSxcbiAgICAgIGludGVybmFsT3BlbiA9IF9SZWFjdCR1c2VTdGF0ZThbMF0sXG4gICAgICBzZXRJbnRlcm5hbE9wZW4gPSBfUmVhY3QkdXNlU3RhdGU4WzFdO1xuXG4gICAgLy8gUmVuZGVyIHN0aWxsIHVzZSBwcm9wcyBhcyBmaXJzdCBwcmlvcml0eVxuICAgIHZhciBtZXJnZWRPcGVuID0gcG9wdXBWaXNpYmxlICE9PSBudWxsICYmIHBvcHVwVmlzaWJsZSAhPT0gdm9pZCAwID8gcG9wdXBWaXNpYmxlIDogaW50ZXJuYWxPcGVuO1xuXG4gICAgLy8gV2UgdXNlIGVmZmVjdCBzeW5jIGhlcmUgaW4gY2FzZSBgcG9wdXBWaXNpYmxlYCBiYWNrIHRvIGB1bmRlZmluZWRgXG4gICAgdmFyIHNldE1lcmdlZE9wZW4gPSB1c2VFdmVudChmdW5jdGlvbiAobmV4dE9wZW4pIHtcbiAgICAgIGlmIChwb3B1cFZpc2libGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzZXRJbnRlcm5hbE9wZW4obmV4dE9wZW4pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRJbnRlcm5hbE9wZW4ocG9wdXBWaXNpYmxlIHx8IGZhbHNlKTtcbiAgICB9LCBbcG9wdXBWaXNpYmxlXSk7XG4gICAgdmFyIG9wZW5SZWYgPSBSZWFjdC51c2VSZWYobWVyZ2VkT3Blbik7XG4gICAgb3BlblJlZi5jdXJyZW50ID0gbWVyZ2VkT3BlbjtcbiAgICB2YXIgaW50ZXJuYWxUcmlnZ2VyT3BlbiA9IHVzZUV2ZW50KGZ1bmN0aW9uIChuZXh0T3Blbikge1xuICAgICAgaWYgKG1lcmdlZE9wZW4gIT09IG5leHRPcGVuKSB7XG4gICAgICAgIHNldE1lcmdlZE9wZW4obmV4dE9wZW4pO1xuICAgICAgICBvblBvcHVwVmlzaWJsZUNoYW5nZSA9PT0gbnVsbCB8fCBvblBvcHVwVmlzaWJsZUNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25Qb3B1cFZpc2libGVDaGFuZ2UobmV4dE9wZW4pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gVHJpZ2dlciBmb3IgZGVsYXlcbiAgICB2YXIgZGVsYXlSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgICB2YXIgY2xlYXJEZWxheSA9IGZ1bmN0aW9uIGNsZWFyRGVsYXkoKSB7XG4gICAgICBjbGVhclRpbWVvdXQoZGVsYXlSZWYuY3VycmVudCk7XG4gICAgfTtcbiAgICB2YXIgdHJpZ2dlck9wZW4gPSBmdW5jdGlvbiB0cmlnZ2VyT3BlbihuZXh0T3Blbikge1xuICAgICAgdmFyIGRlbGF5ID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAwO1xuICAgICAgY2xlYXJEZWxheSgpO1xuICAgICAgaWYgKGRlbGF5ID09PSAwKSB7XG4gICAgICAgIGludGVybmFsVHJpZ2dlck9wZW4obmV4dE9wZW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsYXlSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGludGVybmFsVHJpZ2dlck9wZW4obmV4dE9wZW4pO1xuICAgICAgICB9LCBkZWxheSAqIDEwMDApO1xuICAgICAgfVxuICAgIH07XG4gICAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBjbGVhckRlbGF5O1xuICAgIH0sIFtdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IE1vdGlvbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIF9SZWFjdCR1c2VTdGF0ZTkgPSBSZWFjdC51c2VTdGF0ZShmYWxzZSksXG4gICAgICBfUmVhY3QkdXNlU3RhdGUxMCA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTksIDIpLFxuICAgICAgaW5Nb3Rpb24gPSBfUmVhY3QkdXNlU3RhdGUxMFswXSxcbiAgICAgIHNldEluTW90aW9uID0gX1JlYWN0JHVzZVN0YXRlMTBbMV07XG4gICAgdmFyIG1vdW50UmVmID0gUmVhY3QudXNlUmVmKHRydWUpO1xuICAgIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIW1vdW50UmVmLmN1cnJlbnQgfHwgbWVyZ2VkT3Blbikge1xuICAgICAgICBzZXRJbk1vdGlvbih0cnVlKTtcbiAgICAgIH1cbiAgICAgIG1vdW50UmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH0sIFttZXJnZWRPcGVuXSk7XG4gICAgdmFyIF9SZWFjdCR1c2VTdGF0ZTExID0gUmVhY3QudXNlU3RhdGUobnVsbCksXG4gICAgICBfUmVhY3QkdXNlU3RhdGUxMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTExLCAyKSxcbiAgICAgIG1vdGlvblByZXBhcmVSZXNvbHZlID0gX1JlYWN0JHVzZVN0YXRlMTJbMF0sXG4gICAgICBzZXRNb3Rpb25QcmVwYXJlUmVzb2x2ZSA9IF9SZWFjdCR1c2VTdGF0ZTEyWzFdO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IEFsaWduID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlMTMgPSBSZWFjdC51c2VTdGF0ZShbMCwgMF0pLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlMTQgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUxMywgMiksXG4gICAgICBtb3VzZVBvcyA9IF9SZWFjdCR1c2VTdGF0ZTE0WzBdLFxuICAgICAgc2V0TW91c2VQb3MgPSBfUmVhY3QkdXNlU3RhdGUxNFsxXTtcbiAgICB2YXIgc2V0TW91c2VQb3NCeUV2ZW50ID0gZnVuY3Rpb24gc2V0TW91c2VQb3NCeUV2ZW50KGV2ZW50KSB7XG4gICAgICBzZXRNb3VzZVBvcyhbZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WV0pO1xuICAgIH07XG4gICAgdmFyIF91c2VBbGlnbiA9IHVzZUFsaWduKG1lcmdlZE9wZW4sIHBvcHVwRWxlLCBhbGlnblBvaW50ID8gbW91c2VQb3MgOiB0YXJnZXRFbGUsIHBvcHVwUGxhY2VtZW50LCBidWlsdGluUGxhY2VtZW50cywgcG9wdXBBbGlnbiwgb25Qb3B1cEFsaWduKSxcbiAgICAgIF91c2VBbGlnbjIgPSBfc2xpY2VkVG9BcnJheShfdXNlQWxpZ24sIDkpLFxuICAgICAgcmVhZHkgPSBfdXNlQWxpZ24yWzBdLFxuICAgICAgb2Zmc2V0WCA9IF91c2VBbGlnbjJbMV0sXG4gICAgICBvZmZzZXRZID0gX3VzZUFsaWduMlsyXSxcbiAgICAgIGFycm93WCA9IF91c2VBbGlnbjJbM10sXG4gICAgICBhcnJvd1kgPSBfdXNlQWxpZ24yWzRdLFxuICAgICAgc2NhbGVYID0gX3VzZUFsaWduMls1XSxcbiAgICAgIHNjYWxlWSA9IF91c2VBbGlnbjJbNl0sXG4gICAgICBhbGlnbkluZm8gPSBfdXNlQWxpZ24yWzddLFxuICAgICAgb25BbGlnbiA9IF91c2VBbGlnbjJbOF07XG4gICAgdmFyIHRyaWdnZXJBbGlnbiA9IHVzZUV2ZW50KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghaW5Nb3Rpb24pIHtcbiAgICAgICAgb25BbGlnbigpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHVzZVdhdGNoKG1lcmdlZE9wZW4sIHRhcmdldEVsZSwgcG9wdXBFbGUsIHRyaWdnZXJBbGlnbik7XG4gICAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHRyaWdnZXJBbGlnbigpO1xuICAgIH0sIFttb3VzZVBvc10pO1xuXG4gICAgLy8gV2hlbiBubyBidWlsdGluUGxhY2VtZW50cyBhbmQgcG9wdXBBbGlnbiBjaGFuZ2VkXG4gICAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChtZXJnZWRPcGVuICYmICEoYnVpbHRpblBsYWNlbWVudHMgIT09IG51bGwgJiYgYnVpbHRpblBsYWNlbWVudHMgIT09IHZvaWQgMCAmJiBidWlsdGluUGxhY2VtZW50c1twb3B1cFBsYWNlbWVudF0pKSB7XG4gICAgICAgIHRyaWdnZXJBbGlnbigpO1xuICAgICAgfVxuICAgIH0sIFtKU09OLnN0cmluZ2lmeShwb3B1cEFsaWduKV0pO1xuICAgIHZhciBhbGlnbmVkQ2xhc3NOYW1lID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgYmFzZUNsYXNzTmFtZSA9IGdldEFsaWduUG9wdXBDbGFzc05hbWUoYnVpbHRpblBsYWNlbWVudHMsIHByZWZpeENscywgYWxpZ25JbmZvLCBhbGlnblBvaW50KTtcbiAgICAgIHJldHVybiBjbGFzc05hbWVzKGJhc2VDbGFzc05hbWUsIGdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduID09PSBudWxsIHx8IGdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduID09PSB2b2lkIDAgPyB2b2lkIDAgOiBnZXRQb3B1cENsYXNzTmFtZUZyb21BbGlnbihhbGlnbkluZm8pKTtcbiAgICB9LCBbYWxpZ25JbmZvLCBnZXRQb3B1cENsYXNzTmFtZUZyb21BbGlnbiwgYnVpbHRpblBsYWNlbWVudHMsIHByZWZpeENscywgYWxpZ25Qb2ludF0pO1xuICAgIFJlYWN0LnVzZUltcGVyYXRpdmVIYW5kbGUocmVmLCBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmb3JjZUFsaWduOiB0cmlnZ2VyQWxpZ25cbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBNb3Rpb24gPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBvblZpc2libGVDaGFuZ2VkID0gZnVuY3Rpb24gb25WaXNpYmxlQ2hhbmdlZCh2aXNpYmxlKSB7XG4gICAgICBzZXRJbk1vdGlvbihmYWxzZSk7XG4gICAgICBvbkFsaWduKCk7XG4gICAgICBhZnRlclBvcHVwVmlzaWJsZUNoYW5nZSA9PT0gbnVsbCB8fCBhZnRlclBvcHVwVmlzaWJsZUNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2UodmlzaWJsZSk7XG4gICAgfTtcblxuICAgIC8vIFdlIHdpbGwgdHJpZ2dlciBhbGlnbiB3aGVuIG1vdGlvbiBpcyBpbiBwcmVwYXJlXG4gICAgdmFyIG9uUHJlcGFyZSA9IGZ1bmN0aW9uIG9uUHJlcGFyZSgpIHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICBzZXRNb3Rpb25QcmVwYXJlUmVzb2x2ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfTtcbiAgICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKG1vdGlvblByZXBhcmVSZXNvbHZlKSB7XG4gICAgICAgIG9uQWxpZ24oKTtcbiAgICAgICAgbW90aW9uUHJlcGFyZVJlc29sdmUoKTtcbiAgICAgICAgc2V0TW90aW9uUHJlcGFyZVJlc29sdmUobnVsbCk7XG4gICAgICB9XG4gICAgfSwgW21vdGlvblByZXBhcmVSZXNvbHZlXSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBTdHJldGNoID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBfUmVhY3QkdXNlU3RhdGUxNSA9IFJlYWN0LnVzZVN0YXRlKDApLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlMTYgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUxNSwgMiksXG4gICAgICB0YXJnZXRXaWR0aCA9IF9SZWFjdCR1c2VTdGF0ZTE2WzBdLFxuICAgICAgc2V0VGFyZ2V0V2lkdGggPSBfUmVhY3QkdXNlU3RhdGUxNlsxXTtcbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlMTcgPSBSZWFjdC51c2VTdGF0ZSgwKSxcbiAgICAgIF9SZWFjdCR1c2VTdGF0ZTE4ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMTcsIDIpLFxuICAgICAgdGFyZ2V0SGVpZ2h0ID0gX1JlYWN0JHVzZVN0YXRlMThbMF0sXG4gICAgICBzZXRUYXJnZXRIZWlnaHQgPSBfUmVhY3QkdXNlU3RhdGUxOFsxXTtcbiAgICB2YXIgb25UYXJnZXRSZXNpemUgPSBmdW5jdGlvbiBvblRhcmdldFJlc2l6ZShfLCBlbGUpIHtcbiAgICAgIHRyaWdnZXJBbGlnbigpO1xuICAgICAgaWYgKHN0cmV0Y2gpIHtcbiAgICAgICAgdmFyIHJlY3QgPSBlbGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHNldFRhcmdldFdpZHRoKHJlY3Qud2lkdGgpO1xuICAgICAgICBzZXRUYXJnZXRIZWlnaHQocmVjdC5oZWlnaHQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gQWN0aW9uID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBfdXNlQWN0aW9uID0gdXNlQWN0aW9uKG1vYmlsZSwgYWN0aW9uLCBzaG93QWN0aW9uLCBoaWRlQWN0aW9uKSxcbiAgICAgIF91c2VBY3Rpb24yID0gX3NsaWNlZFRvQXJyYXkoX3VzZUFjdGlvbiwgMiksXG4gICAgICBzaG93QWN0aW9ucyA9IF91c2VBY3Rpb24yWzBdLFxuICAgICAgaGlkZUFjdGlvbnMgPSBfdXNlQWN0aW9uMlsxXTtcblxuICAgIC8vIFV0aWwgd3JhcHBlciBmb3IgdHJpZ2dlciBhY3Rpb25cbiAgICB2YXIgd3JhcHBlckFjdGlvbiA9IGZ1bmN0aW9uIHdyYXBwZXJBY3Rpb24oZXZlbnROYW1lLCBuZXh0T3BlbiwgZGVsYXksIHByZUV2ZW50KSB7XG4gICAgICBjbG9uZVByb3BzW2V2ZW50TmFtZV0gPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdmFyIF9vcmlnaW5DaGlsZFByb3BzJGV2ZTtcbiAgICAgICAgcHJlRXZlbnQgPT09IG51bGwgfHwgcHJlRXZlbnQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHByZUV2ZW50KGV2ZW50KTtcbiAgICAgICAgdHJpZ2dlck9wZW4obmV4dE9wZW4sIGRlbGF5KTtcblxuICAgICAgICAvLyBQYXNzIHRvIG9yaWdpblxuICAgICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICAgIH1cbiAgICAgICAgKF9vcmlnaW5DaGlsZFByb3BzJGV2ZSA9IG9yaWdpbkNoaWxkUHJvcHNbZXZlbnROYW1lXSkgPT09IG51bGwgfHwgX29yaWdpbkNoaWxkUHJvcHMkZXZlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfb3JpZ2luQ2hpbGRQcm9wcyRldmUuY2FsbC5hcHBseShfb3JpZ2luQ2hpbGRQcm9wcyRldmUsIFtvcmlnaW5DaGlsZFByb3BzLCBldmVudF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgIH07XG4gICAgfTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09IEFjdGlvbjogQ2xpY2sgPT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIGNsaWNrVG9TaG93ID0gc2hvd0FjdGlvbnMuaGFzKCdjbGljaycpO1xuICAgIHZhciBjbGlja1RvSGlkZSA9IGhpZGVBY3Rpb25zLmhhcygnY2xpY2snKSB8fCBoaWRlQWN0aW9ucy5oYXMoJ2NvbnRleHRNZW51Jyk7XG4gICAgaWYgKGNsaWNrVG9TaG93IHx8IGNsaWNrVG9IaWRlKSB7XG4gICAgICBjbG9uZVByb3BzLm9uQ2xpY2sgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdmFyIF9vcmlnaW5DaGlsZFByb3BzJG9uQztcbiAgICAgICAgaWYgKG9wZW5SZWYuY3VycmVudCAmJiBjbGlja1RvSGlkZSkge1xuICAgICAgICAgIHRyaWdnZXJPcGVuKGZhbHNlKTtcbiAgICAgICAgfSBlbHNlIGlmICghb3BlblJlZi5jdXJyZW50ICYmIGNsaWNrVG9TaG93KSB7XG4gICAgICAgICAgc2V0TW91c2VQb3NCeUV2ZW50KGV2ZW50KTtcbiAgICAgICAgICB0cmlnZ2VyT3Blbih0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFBhc3MgdG8gb3JpZ2luXG4gICAgICAgIGZvciAodmFyIF9sZW4yID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMiA+IDEgPyBfbGVuMiAtIDEgOiAwKSwgX2tleTIgPSAxOyBfa2V5MiA8IF9sZW4yOyBfa2V5MisrKSB7XG4gICAgICAgICAgYXJnc1tfa2V5MiAtIDFdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICAgICAgfVxuICAgICAgICAoX29yaWdpbkNoaWxkUHJvcHMkb25DID0gb3JpZ2luQ2hpbGRQcm9wcy5vbkNsaWNrKSA9PT0gbnVsbCB8fCBfb3JpZ2luQ2hpbGRQcm9wcyRvbkMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9vcmlnaW5DaGlsZFByb3BzJG9uQy5jYWxsLmFwcGx5KF9vcmlnaW5DaGlsZFByb3BzJG9uQywgW29yaWdpbkNoaWxkUHJvcHMsIGV2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBDbGljayB0byBoaWRlIGlzIHNwZWNpYWwgYWN0aW9uIHNpbmNlIGNsaWNrIHBvcHVwIGVsZW1lbnQgc2hvdWxkIG5vdCBoaWRlXG4gICAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChjbGlja1RvSGlkZSAmJiBwb3B1cEVsZSAmJiAoIW1hc2sgfHwgbWFza0Nsb3NhYmxlKSkge1xuICAgICAgICB2YXIgY2xpY2tJbnNpZGUgPSBmYWxzZTtcblxuICAgICAgICAvLyBVc2VyIG1heSBtb3VzZURvd24gaW5zaWRlIGFuZCBkcmFnIG91dCBvZiBwb3B1cCBhbmQgbW91c2UgdXBcbiAgICAgICAgLy8gUmVjb3JkIGhlcmUgdG8gcHJldmVudCBjbG9zZVxuICAgICAgICB2YXIgb25XaW5kb3dNb3VzZURvd24gPSBmdW5jdGlvbiBvbldpbmRvd01vdXNlRG93bihfcmVmKSB7XG4gICAgICAgICAgdmFyIHRhcmdldCA9IF9yZWYudGFyZ2V0O1xuICAgICAgICAgIGNsaWNrSW5zaWRlID0gaW5Qb3B1cE9yQ2hpbGQodGFyZ2V0KTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG9uV2luZG93Q2xpY2sgPSBmdW5jdGlvbiBvbldpbmRvd0NsaWNrKF9yZWYyKSB7XG4gICAgICAgICAgdmFyIHRhcmdldCA9IF9yZWYyLnRhcmdldDtcbiAgICAgICAgICBpZiAob3BlblJlZi5jdXJyZW50ICYmICFjbGlja0luc2lkZSAmJiAhaW5Qb3B1cE9yQ2hpbGQodGFyZ2V0KSkge1xuICAgICAgICAgICAgdHJpZ2dlck9wZW4oZmFsc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHdpbiA9IGdldFdpbihwb3B1cEVsZSk7XG4gICAgICAgIHZhciB0YXJnZXRSb290ID0gdGFyZ2V0RWxlID09PSBudWxsIHx8IHRhcmdldEVsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogdGFyZ2V0RWxlLmdldFJvb3ROb2RlKCk7XG4gICAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBvbldpbmRvd01vdXNlRG93bik7XG4gICAgICAgIHdpbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uV2luZG93Q2xpY2spO1xuXG4gICAgICAgIC8vIHNoYWRvdyByb290XG4gICAgICAgIHZhciBpblNoYWRvdyA9IHRhcmdldFJvb3QgJiYgdGFyZ2V0Um9vdCAhPT0gdGFyZ2V0RWxlLm93bmVyRG9jdW1lbnQ7XG4gICAgICAgIGlmIChpblNoYWRvdykge1xuICAgICAgICAgIHRhcmdldFJvb3QuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25XaW5kb3dNb3VzZURvd24pO1xuICAgICAgICAgIHRhcmdldFJvb3QuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbldpbmRvd0NsaWNrKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFdhcm5pbmcgaWYgdGFyZ2V0IGFuZCBwb3B1cCBub3QgaW4gc2FtZSByb290XG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgICAgICAgdmFyIHBvcHVwUm9vdCA9IHBvcHVwRWxlLmdldFJvb3ROb2RlKCk7XG4gICAgICAgICAgd2FybmluZyh0YXJnZXRSb290ID09PSBwb3B1cFJvb3QsIFwidHJpZ2dlciBlbGVtZW50IGFuZCBwb3B1cCBlbGVtZW50IHNob3VsZCBpbiBzYW1lIHNoYWRvdyByb290LlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBvbldpbmRvd01vdXNlRG93bik7XG4gICAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25XaW5kb3dDbGljayk7XG4gICAgICAgICAgaWYgKGluU2hhZG93KSB7XG4gICAgICAgICAgICB0YXJnZXRSb290LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uV2luZG93TW91c2VEb3duKTtcbiAgICAgICAgICAgIHRhcmdldFJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbldpbmRvd0NsaWNrKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSwgW2NsaWNrVG9IaWRlLCB0YXJnZXRFbGUsIHBvcHVwRWxlLCBtYXNrLCBtYXNrQ2xvc2FibGVdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09IEFjdGlvbjogSG92ZXIgPT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIGhvdmVyVG9TaG93ID0gc2hvd0FjdGlvbnMuaGFzKCdob3ZlcicpO1xuICAgIHZhciBob3ZlclRvSGlkZSA9IGhpZGVBY3Rpb25zLmhhcygnaG92ZXInKTtcbiAgICB2YXIgb25Qb3B1cE1vdXNlRW50ZXI7XG4gICAgdmFyIG9uUG9wdXBNb3VzZUxlYXZlO1xuICAgIGlmIChob3ZlclRvU2hvdykge1xuICAgICAgd3JhcHBlckFjdGlvbignb25Nb3VzZUVudGVyJywgdHJ1ZSwgbW91c2VFbnRlckRlbGF5LCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgc2V0TW91c2VQb3NCeUV2ZW50KGV2ZW50KTtcbiAgICAgIH0pO1xuICAgICAgb25Qb3B1cE1vdXNlRW50ZXIgPSBmdW5jdGlvbiBvblBvcHVwTW91c2VFbnRlcigpIHtcbiAgICAgICAgdHJpZ2dlck9wZW4odHJ1ZSwgbW91c2VFbnRlckRlbGF5KTtcbiAgICAgIH07XG5cbiAgICAgIC8vIEFsaWduIFBvaW50XG4gICAgICBpZiAoYWxpZ25Qb2ludCkge1xuICAgICAgICBjbG9uZVByb3BzLm9uTW91c2VNb3ZlID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgdmFyIF9vcmlnaW5DaGlsZFByb3BzJG9uTTtcbiAgICAgICAgICAvLyBzZXRNb3VzZVBvc0J5RXZlbnQoZXZlbnQpO1xuICAgICAgICAgIChfb3JpZ2luQ2hpbGRQcm9wcyRvbk0gPSBvcmlnaW5DaGlsZFByb3BzLm9uTW91c2VNb3ZlKSA9PT0gbnVsbCB8fCBfb3JpZ2luQ2hpbGRQcm9wcyRvbk0gPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9vcmlnaW5DaGlsZFByb3BzJG9uTS5jYWxsKG9yaWdpbkNoaWxkUHJvcHMsIGV2ZW50KTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGhvdmVyVG9IaWRlKSB7XG4gICAgICB3cmFwcGVyQWN0aW9uKCdvbk1vdXNlTGVhdmUnLCBmYWxzZSwgbW91c2VMZWF2ZURlbGF5KTtcbiAgICAgIG9uUG9wdXBNb3VzZUxlYXZlID0gZnVuY3Rpb24gb25Qb3B1cE1vdXNlTGVhdmUoKSB7XG4gICAgICAgIHRyaWdnZXJPcGVuKGZhbHNlLCBtb3VzZUxlYXZlRGVsYXkpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PSBBY3Rpb246IEZvY3VzID09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIGlmIChzaG93QWN0aW9ucy5oYXMoJ2ZvY3VzJykpIHtcbiAgICAgIHdyYXBwZXJBY3Rpb24oJ29uRm9jdXMnLCB0cnVlLCBmb2N1c0RlbGF5KTtcbiAgICB9XG4gICAgaWYgKGhpZGVBY3Rpb25zLmhhcygnZm9jdXMnKSkge1xuICAgICAgd3JhcHBlckFjdGlvbignb25CbHVyJywgZmFsc2UsIGJsdXJEZWxheSk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT0gQWN0aW9uOiBDb250ZXh0TWVudSA9PT09PT09PT09PT09PT09PT09PT1cbiAgICBpZiAoc2hvd0FjdGlvbnMuaGFzKCdjb250ZXh0TWVudScpKSB7XG4gICAgICBjbG9uZVByb3BzLm9uQ29udGV4dE1lbnUgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdmFyIF9vcmlnaW5DaGlsZFByb3BzJG9uQzI7XG4gICAgICAgIHNldE1vdXNlUG9zQnlFdmVudChldmVudCk7XG4gICAgICAgIHRyaWdnZXJPcGVuKHRydWUpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIC8vIFBhc3MgdG8gb3JpZ2luXG4gICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyA+IDEgPyBfbGVuMyAtIDEgOiAwKSwgX2tleTMgPSAxOyBfa2V5MyA8IF9sZW4zOyBfa2V5MysrKSB7XG4gICAgICAgICAgYXJnc1tfa2V5MyAtIDFdID0gYXJndW1lbnRzW19rZXkzXTtcbiAgICAgICAgfVxuICAgICAgICAoX29yaWdpbkNoaWxkUHJvcHMkb25DMiA9IG9yaWdpbkNoaWxkUHJvcHMub25Db250ZXh0TWVudSkgPT09IG51bGwgfHwgX29yaWdpbkNoaWxkUHJvcHMkb25DMiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX29yaWdpbkNoaWxkUHJvcHMkb25DMi5jYWxsLmFwcGx5KF9vcmlnaW5DaGlsZFByb3BzJG9uQzIsIFtvcmlnaW5DaGlsZFByb3BzLCBldmVudF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBDbGFzc05hbWUgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICBpZiAoY2xhc3NOYW1lKSB7XG4gICAgICBjbG9uZVByb3BzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZXMob3JpZ2luQ2hpbGRQcm9wcy5jbGFzc05hbWUsIGNsYXNzTmFtZSk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IFJlbmRlciA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgbWVyZ2VkQ2hpbGRyZW5Qcm9wcyA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgb3JpZ2luQ2hpbGRQcm9wcyksIGNsb25lUHJvcHMpO1xuXG4gICAgLy8gUGFzcyBwcm9wcyBpbnRvIGNsb25lUHJvcHMgZm9yIG5lc3QgdXNhZ2VcbiAgICB2YXIgcGFzc2VkUHJvcHMgPSB7fTtcbiAgICB2YXIgcGFzc2VkRXZlbnRMaXN0ID0gWydvbkNvbnRleHRNZW51JywgJ29uQ2xpY2snLCAnb25Nb3VzZURvd24nLCAnb25Ub3VjaFN0YXJ0JywgJ29uTW91c2VFbnRlcicsICdvbk1vdXNlTGVhdmUnLCAnb25Gb2N1cycsICdvbkJsdXInXTtcbiAgICBwYXNzZWRFdmVudExpc3QuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnROYW1lKSB7XG4gICAgICBpZiAocmVzdFByb3BzW2V2ZW50TmFtZV0pIHtcbiAgICAgICAgcGFzc2VkUHJvcHNbZXZlbnROYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgX21lcmdlZENoaWxkcmVuUHJvcHMkO1xuICAgICAgICAgIGZvciAodmFyIF9sZW40ID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuNCksIF9rZXk0ID0gMDsgX2tleTQgPCBfbGVuNDsgX2tleTQrKykge1xuICAgICAgICAgICAgYXJnc1tfa2V5NF0gPSBhcmd1bWVudHNbX2tleTRdO1xuICAgICAgICAgIH1cbiAgICAgICAgICAoX21lcmdlZENoaWxkcmVuUHJvcHMkID0gbWVyZ2VkQ2hpbGRyZW5Qcm9wc1tldmVudE5hbWVdKSA9PT0gbnVsbCB8fCBfbWVyZ2VkQ2hpbGRyZW5Qcm9wcyQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9tZXJnZWRDaGlsZHJlblByb3BzJC5jYWxsLmFwcGx5KF9tZXJnZWRDaGlsZHJlblByb3BzJCwgW21lcmdlZENoaWxkcmVuUHJvcHNdLmNvbmNhdChhcmdzKSk7XG4gICAgICAgICAgcmVzdFByb3BzW2V2ZW50TmFtZV0uYXBwbHkocmVzdFByb3BzLCBhcmdzKTtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIENoaWxkIE5vZGVcbiAgICB2YXIgdHJpZ2dlck5vZGUgPSAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KGNoaWxkLCBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIG1lcmdlZENoaWxkcmVuUHJvcHMpLCBwYXNzZWRQcm9wcykpO1xuICAgIHZhciBhcnJvd1BvcyA9IHtcbiAgICAgIHg6IGFycm93WCxcbiAgICAgIHk6IGFycm93WVxuICAgIH07XG4gICAgdmFyIGlubmVyQXJyb3cgPSBhcnJvdyA/IF9vYmplY3RTcHJlYWQoe30sIGFycm93ICE9PSB0cnVlID8gYXJyb3cgOiB7fSkgOiBudWxsO1xuXG4gICAgLy8gUmVuZGVyXG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0LkZyYWdtZW50LCBudWxsLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChSZXNpemVPYnNlcnZlciwge1xuICAgICAgZGlzYWJsZWQ6ICFtZXJnZWRPcGVuLFxuICAgICAgcmVmOiBzZXRUYXJnZXRSZWYsXG4gICAgICBvblJlc2l6ZTogb25UYXJnZXRSZXNpemVcbiAgICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUcmlnZ2VyV3JhcHBlciwge1xuICAgICAgZ2V0VHJpZ2dlckRPTU5vZGU6IGdldFRyaWdnZXJET01Ob2RlXG4gICAgfSwgdHJpZ2dlck5vZGUpKSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoVHJpZ2dlckNvbnRleHQuUHJvdmlkZXIsIHtcbiAgICAgIHZhbHVlOiBjb250ZXh0XG4gICAgfSwgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUG9wdXAsIHtcbiAgICAgIHBvcnRhbDogUG9ydGFsQ29tcG9uZW50LFxuICAgICAgcmVmOiBzZXRQb3B1cFJlZixcbiAgICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgICAgcG9wdXA6IHBvcHVwLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKHBvcHVwQ2xhc3NOYW1lLCBhbGlnbmVkQ2xhc3NOYW1lKSxcbiAgICAgIHN0eWxlOiBwb3B1cFN0eWxlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRFbGUsXG4gICAgICBvbk1vdXNlRW50ZXI6IG9uUG9wdXBNb3VzZUVudGVyLFxuICAgICAgb25Nb3VzZUxlYXZlOiBvblBvcHVwTW91c2VMZWF2ZSxcbiAgICAgIHpJbmRleDogekluZGV4XG4gICAgICAvLyBPcGVuXG4gICAgICAsXG4gICAgICBvcGVuOiBtZXJnZWRPcGVuLFxuICAgICAga2VlcERvbTogaW5Nb3Rpb25cbiAgICAgIC8vIENsaWNrXG4gICAgICAsXG4gICAgICBvbkNsaWNrOiBvblBvcHVwQ2xpY2tcbiAgICAgIC8vIE1hc2tcbiAgICAgICxcbiAgICAgIG1hc2s6IG1hc2tcbiAgICAgIC8vIE1vdGlvblxuICAgICAgLFxuICAgICAgbW90aW9uOiBtZXJnZVBvcHVwTW90aW9uLFxuICAgICAgbWFza01vdGlvbjogbWVyZ2VNYXNrTW90aW9uLFxuICAgICAgb25WaXNpYmxlQ2hhbmdlZDogb25WaXNpYmxlQ2hhbmdlZCxcbiAgICAgIG9uUHJlcGFyZTogb25QcmVwYXJlXG4gICAgICAvLyBQb3J0YWxcbiAgICAgICxcbiAgICAgIGZvcmNlUmVuZGVyOiBmb3JjZVJlbmRlcixcbiAgICAgIGF1dG9EZXN0cm95OiBtZXJnZWRBdXRvRGVzdHJveSxcbiAgICAgIGdldFBvcHVwQ29udGFpbmVyOiBnZXRQb3B1cENvbnRhaW5lclxuICAgICAgLy8gQXJyb3dcbiAgICAgICxcbiAgICAgIGFsaWduOiBhbGlnbkluZm8sXG4gICAgICBhcnJvdzogaW5uZXJBcnJvdyxcbiAgICAgIGFycm93UG9zOiBhcnJvd1Bvc1xuICAgICAgLy8gQWxpZ25cbiAgICAgICxcbiAgICAgIHJlYWR5OiByZWFkeSxcbiAgICAgIG9mZnNldFg6IG9mZnNldFgsXG4gICAgICBvZmZzZXRZOiBvZmZzZXRZLFxuICAgICAgb25BbGlnbjogdHJpZ2dlckFsaWduXG4gICAgICAvLyBTdHJldGNoXG4gICAgICAsXG4gICAgICBzdHJldGNoOiBzdHJldGNoLFxuICAgICAgdGFyZ2V0V2lkdGg6IHRhcmdldFdpZHRoIC8gc2NhbGVYLFxuICAgICAgdGFyZ2V0SGVpZ2h0OiB0YXJnZXRIZWlnaHQgLyBzY2FsZVlcbiAgICB9KSkpO1xuICB9KTtcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICBUcmlnZ2VyLmRpc3BsYXlOYW1lID0gJ1RyaWdnZXInO1xuICB9XG4gIHJldHVybiBUcmlnZ2VyO1xufVxuZXhwb3J0IGRlZmF1bHQgZ2VuZXJhdGVUcmlnZ2VyKFBvcnRhbCk7IiwidmFyIGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSA9IHtcbiAgc2hpZnRYOiA2NCxcbiAgYWRqdXN0WTogMVxufTtcbnZhciBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQgPSB7XG4gIGFkanVzdFg6IDEsXG4gIHNoaWZ0WTogdHJ1ZVxufTtcbnZhciB0YXJnZXRPZmZzZXQgPSBbMCwgMF07XG5leHBvcnQgdmFyIHBsYWNlbWVudHMgPSB7XG4gIGxlZnQ6IHtcbiAgICBwb2ludHM6IFsnY3InLCAnY2wnXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93TGVmdFJpZ2h0LFxuICAgIG9mZnNldDogWy00LCAwXSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICByaWdodDoge1xuICAgIHBvaW50czogWydjbCcsICdjciddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbNCwgMF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgdG9wOiB7XG4gICAgcG9pbnRzOiBbJ2JjJywgJ3RjJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCAtNF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgYm90dG9tOiB7XG4gICAgcG9pbnRzOiBbJ3RjJywgJ2JjJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCA0XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICB0b3BMZWZ0OiB7XG4gICAgcG9pbnRzOiBbJ2JsJywgJ3RsJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCAtNF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgbGVmdFRvcDoge1xuICAgIHBvaW50czogWyd0cicsICd0bCddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbLTQsIDBdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH0sXG4gIHRvcFJpZ2h0OiB7XG4gICAgcG9pbnRzOiBbJ2JyJywgJ3RyJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCAtNF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgcmlnaHRUb3A6IHtcbiAgICBwb2ludHM6IFsndGwnLCAndHInXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93TGVmdFJpZ2h0LFxuICAgIG9mZnNldDogWzQsIDBdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH0sXG4gIGJvdHRvbVJpZ2h0OiB7XG4gICAgcG9pbnRzOiBbJ3RyJywgJ2JyJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCA0XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICByaWdodEJvdHRvbToge1xuICAgIHBvaW50czogWydibCcsICdiciddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbNCwgMF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgYm90dG9tTGVmdDoge1xuICAgIHBvaW50czogWyd0bCcsICdibCddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dUb3BCb3R0b20sXG4gICAgb2Zmc2V0OiBbMCwgNF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgbGVmdEJvdHRvbToge1xuICAgIHBvaW50czogWydicicsICdibCddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbLTQsIDBdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH1cbn07XG5leHBvcnQgZGVmYXVsdCBwbGFjZW1lbnRzOyIsImltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUG9wdXAocHJvcHMpIHtcbiAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIGlkID0gcHJvcHMuaWQsXG4gICAgb3ZlcmxheUlubmVyU3R5bGUgPSBwcm9wcy5vdmVybGF5SW5uZXJTdHlsZSxcbiAgICBjbGFzc05hbWUgPSBwcm9wcy5jbGFzc05hbWUsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMoXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1jb250ZW50XCIpLCBjbGFzc05hbWUpLFxuICAgIHN0eWxlOiBzdHlsZVxuICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWlubmVyXCIpLFxuICAgIGlkOiBpZCxcbiAgICByb2xlOiBcInRvb2x0aXBcIixcbiAgICBzdHlsZTogb3ZlcmxheUlubmVyU3R5bGVcbiAgfSwgdHlwZW9mIGNoaWxkcmVuID09PSAnZnVuY3Rpb24nID8gY2hpbGRyZW4oKSA6IGNoaWxkcmVuKSk7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJvdmVybGF5Q2xhc3NOYW1lXCIsIFwidHJpZ2dlclwiLCBcIm1vdXNlRW50ZXJEZWxheVwiLCBcIm1vdXNlTGVhdmVEZWxheVwiLCBcIm92ZXJsYXlTdHlsZVwiLCBcInByZWZpeENsc1wiLCBcImNoaWxkcmVuXCIsIFwib25WaXNpYmxlQ2hhbmdlXCIsIFwiYWZ0ZXJWaXNpYmxlQ2hhbmdlXCIsIFwidHJhbnNpdGlvbk5hbWVcIiwgXCJhbmltYXRpb25cIiwgXCJtb3Rpb25cIiwgXCJwbGFjZW1lbnRcIiwgXCJhbGlnblwiLCBcImRlc3Ryb3lUb29sdGlwT25IaWRlXCIsIFwiZGVmYXVsdFZpc2libGVcIiwgXCJnZXRUb29sdGlwQ29udGFpbmVyXCIsIFwib3ZlcmxheUlubmVyU3R5bGVcIiwgXCJhcnJvd0NvbnRlbnRcIiwgXCJvdmVybGF5XCIsIFwiaWRcIiwgXCJzaG93QXJyb3dcIl07XG5pbXBvcnQgVHJpZ2dlciBmcm9tICdAcmMtY29tcG9uZW50L3RyaWdnZXInO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgZm9yd2FyZFJlZiwgdXNlSW1wZXJhdGl2ZUhhbmRsZSwgdXNlUmVmIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcGxhY2VtZW50cyB9IGZyb20gXCIuL3BsYWNlbWVudHNcIjtcbmltcG9ydCBQb3B1cCBmcm9tIFwiLi9Qb3B1cFwiO1xudmFyIFRvb2x0aXAgPSBmdW5jdGlvbiBUb29sdGlwKHByb3BzLCByZWYpIHtcbiAgdmFyIG92ZXJsYXlDbGFzc05hbWUgPSBwcm9wcy5vdmVybGF5Q2xhc3NOYW1lLFxuICAgIF9wcm9wcyR0cmlnZ2VyID0gcHJvcHMudHJpZ2dlcixcbiAgICB0cmlnZ2VyID0gX3Byb3BzJHRyaWdnZXIgPT09IHZvaWQgMCA/IFsnaG92ZXInXSA6IF9wcm9wcyR0cmlnZ2VyLFxuICAgIF9wcm9wcyRtb3VzZUVudGVyRGVsYSA9IHByb3BzLm1vdXNlRW50ZXJEZWxheSxcbiAgICBtb3VzZUVudGVyRGVsYXkgPSBfcHJvcHMkbW91c2VFbnRlckRlbGEgPT09IHZvaWQgMCA/IDAgOiBfcHJvcHMkbW91c2VFbnRlckRlbGEsXG4gICAgX3Byb3BzJG1vdXNlTGVhdmVEZWxhID0gcHJvcHMubW91c2VMZWF2ZURlbGF5LFxuICAgIG1vdXNlTGVhdmVEZWxheSA9IF9wcm9wcyRtb3VzZUxlYXZlRGVsYSA9PT0gdm9pZCAwID8gMC4xIDogX3Byb3BzJG1vdXNlTGVhdmVEZWxhLFxuICAgIG92ZXJsYXlTdHlsZSA9IHByb3BzLm92ZXJsYXlTdHlsZSxcbiAgICBfcHJvcHMkcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIHByZWZpeENscyA9IF9wcm9wcyRwcmVmaXhDbHMgPT09IHZvaWQgMCA/ICdyYy10b29sdGlwJyA6IF9wcm9wcyRwcmVmaXhDbHMsXG4gICAgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbixcbiAgICBvblZpc2libGVDaGFuZ2UgPSBwcm9wcy5vblZpc2libGVDaGFuZ2UsXG4gICAgYWZ0ZXJWaXNpYmxlQ2hhbmdlID0gcHJvcHMuYWZ0ZXJWaXNpYmxlQ2hhbmdlLFxuICAgIHRyYW5zaXRpb25OYW1lID0gcHJvcHMudHJhbnNpdGlvbk5hbWUsXG4gICAgYW5pbWF0aW9uID0gcHJvcHMuYW5pbWF0aW9uLFxuICAgIG1vdGlvbiA9IHByb3BzLm1vdGlvbixcbiAgICBfcHJvcHMkcGxhY2VtZW50ID0gcHJvcHMucGxhY2VtZW50LFxuICAgIHBsYWNlbWVudCA9IF9wcm9wcyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/ICdyaWdodCcgOiBfcHJvcHMkcGxhY2VtZW50LFxuICAgIF9wcm9wcyRhbGlnbiA9IHByb3BzLmFsaWduLFxuICAgIGFsaWduID0gX3Byb3BzJGFsaWduID09PSB2b2lkIDAgPyB7fSA6IF9wcm9wcyRhbGlnbixcbiAgICBfcHJvcHMkZGVzdHJveVRvb2x0aXAgPSBwcm9wcy5kZXN0cm95VG9vbHRpcE9uSGlkZSxcbiAgICBkZXN0cm95VG9vbHRpcE9uSGlkZSA9IF9wcm9wcyRkZXN0cm95VG9vbHRpcCA9PT0gdm9pZCAwID8gZmFsc2UgOiBfcHJvcHMkZGVzdHJveVRvb2x0aXAsXG4gICAgZGVmYXVsdFZpc2libGUgPSBwcm9wcy5kZWZhdWx0VmlzaWJsZSxcbiAgICBnZXRUb29sdGlwQ29udGFpbmVyID0gcHJvcHMuZ2V0VG9vbHRpcENvbnRhaW5lcixcbiAgICBvdmVybGF5SW5uZXJTdHlsZSA9IHByb3BzLm92ZXJsYXlJbm5lclN0eWxlLFxuICAgIGFycm93Q29udGVudCA9IHByb3BzLmFycm93Q29udGVudCxcbiAgICBvdmVybGF5ID0gcHJvcHMub3ZlcmxheSxcbiAgICBpZCA9IHByb3BzLmlkLFxuICAgIF9wcm9wcyRzaG93QXJyb3cgPSBwcm9wcy5zaG93QXJyb3csXG4gICAgc2hvd0Fycm93ID0gX3Byb3BzJHNob3dBcnJvdyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRzaG93QXJyb3csXG4gICAgcmVzdFByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKHByb3BzLCBfZXhjbHVkZWQpO1xuICB2YXIgdHJpZ2dlclJlZiA9IHVzZVJlZihudWxsKTtcbiAgdXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdHJpZ2dlclJlZi5jdXJyZW50O1xuICB9KTtcbiAgdmFyIGV4dHJhUHJvcHMgPSBfb2JqZWN0U3ByZWFkKHt9LCByZXN0UHJvcHMpO1xuICBpZiAoJ3Zpc2libGUnIGluIHByb3BzKSB7XG4gICAgZXh0cmFQcm9wcy5wb3B1cFZpc2libGUgPSBwcm9wcy52aXNpYmxlO1xuICB9XG4gIHZhciBnZXRQb3B1cEVsZW1lbnQgPSBmdW5jdGlvbiBnZXRQb3B1cEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFBvcHVwLCB7XG4gICAgICBrZXk6IFwiY29udGVudFwiLFxuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICBpZDogaWQsXG4gICAgICBvdmVybGF5SW5uZXJTdHlsZTogb3ZlcmxheUlubmVyU3R5bGVcbiAgICB9LCBvdmVybGF5KTtcbiAgfTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFRyaWdnZXIsIF9leHRlbmRzKHtcbiAgICBwb3B1cENsYXNzTmFtZTogb3ZlcmxheUNsYXNzTmFtZSxcbiAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICBwb3B1cDogZ2V0UG9wdXBFbGVtZW50LFxuICAgIGFjdGlvbjogdHJpZ2dlcixcbiAgICBidWlsdGluUGxhY2VtZW50czogcGxhY2VtZW50cyxcbiAgICBwb3B1cFBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgIHJlZjogdHJpZ2dlclJlZixcbiAgICBwb3B1cEFsaWduOiBhbGlnbixcbiAgICBnZXRQb3B1cENvbnRhaW5lcjogZ2V0VG9vbHRpcENvbnRhaW5lcixcbiAgICBvblBvcHVwVmlzaWJsZUNoYW5nZTogb25WaXNpYmxlQ2hhbmdlLFxuICAgIGFmdGVyUG9wdXBWaXNpYmxlQ2hhbmdlOiBhZnRlclZpc2libGVDaGFuZ2UsXG4gICAgcG9wdXBUcmFuc2l0aW9uTmFtZTogdHJhbnNpdGlvbk5hbWUsXG4gICAgcG9wdXBBbmltYXRpb246IGFuaW1hdGlvbixcbiAgICBwb3B1cE1vdGlvbjogbW90aW9uLFxuICAgIGRlZmF1bHRQb3B1cFZpc2libGU6IGRlZmF1bHRWaXNpYmxlLFxuICAgIGF1dG9EZXN0cm95OiBkZXN0cm95VG9vbHRpcE9uSGlkZSxcbiAgICBtb3VzZUxlYXZlRGVsYXk6IG1vdXNlTGVhdmVEZWxheSxcbiAgICBwb3B1cFN0eWxlOiBvdmVybGF5U3R5bGUsXG4gICAgbW91c2VFbnRlckRlbGF5OiBtb3VzZUVudGVyRGVsYXksXG4gICAgYXJyb3c6IHNob3dBcnJvd1xuICB9LCBleHRyYVByb3BzKSwgY2hpbGRyZW4pO1xufTtcbmV4cG9ydCBkZWZhdWx0IC8qI19fUFVSRV9fKi9mb3J3YXJkUmVmKFRvb2x0aXApOyIsImltcG9ydCBUb29sdGlwIGZyb20gXCIuL1Rvb2x0aXBcIjtcbmltcG9ydCBQb3B1cCBmcm9tIFwiLi9Qb3B1cFwiO1xuZXhwb3J0IHsgUG9wdXAgfTtcbmV4cG9ydCBkZWZhdWx0IFRvb2x0aXA7IiwiLyoqXG4gKiByYy10b29sdGlwIHRvb2x0aXAgc2xpZGVyXG4gKi9cbnZhciBfX2Fzc2lnbiA9ICh0aGlzICYmIHRoaXMuX19hc3NpZ24pIHx8IGZ1bmN0aW9uICgpIHtcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24odCkge1xuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpXG4gICAgICAgICAgICAgICAgdFtwXSA9IHNbcF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHQ7XG4gICAgfTtcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn07XG52YXIgX19yZXN0ID0gKHRoaXMgJiYgdGhpcy5fX3Jlc3QpIHx8IGZ1bmN0aW9uIChzLCBlKSB7XG4gICAgdmFyIHQgPSB7fTtcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcbiAgICAgICAgdFtwXSA9IHNbcF07XG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XG4gICAgICAgIH1cbiAgICByZXR1cm4gdDtcbn07XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBcInJjLXRvb2x0aXAvYXNzZXRzL2Jvb3RzdHJhcC5jc3NcIjtcbmltcG9ydCBTbGlkZXIgZnJvbSBcInJjLXNsaWRlclwiO1xuaW1wb3J0IHJhZiBmcm9tIFwicmMtdXRpbC9saWIvcmFmXCI7XG5pbXBvcnQgVG9vbHRpcCBmcm9tIFwicmMtdG9vbHRpcFwiO1xudmFyIEhhbmRsZVRvb2x0aXAgPSBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICB2YXIgdmFsdWUgPSBwcm9wcy52YWx1ZSwgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbiwgdmlzaWJsZSA9IHByb3BzLnZpc2libGUsIF9hID0gcHJvcHMudGlwRm9ybWF0dGVyLCB0aXBGb3JtYXR0ZXIgPSBfYSA9PT0gdm9pZCAwID8gZnVuY3Rpb24gKHZhbCkgeyByZXR1cm4gXCJcIi5jb25jYXQodmFsLCBcIiAlXCIpOyB9IDogX2EsIHJlc3RQcm9wcyA9IF9fcmVzdChwcm9wcywgW1widmFsdWVcIiwgXCJjaGlsZHJlblwiLCBcInZpc2libGVcIiwgXCJ0aXBGb3JtYXR0ZXJcIl0pO1xuICAgIHZhciB0b29sdGlwUmVmID0gUmVhY3QudXNlUmVmKCk7XG4gICAgdmFyIHJhZlJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgICBmdW5jdGlvbiBjYW5jZWxLZWVwQWxpZ24oKSB7XG4gICAgICAgIHJhZi5jYW5jZWwocmFmUmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBrZWVwQWxpZ24oKSB7XG4gICAgICAgIHJhZlJlZi5jdXJyZW50ID0gcmFmKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIHRvb2x0aXBSZWYuY3VycmVudD8uZm9yY2VQb3B1cEFsaWduKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodmlzaWJsZSkge1xuICAgICAgICAgICAga2VlcEFsaWduKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjYW5jZWxLZWVwQWxpZ24oKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FuY2VsS2VlcEFsaWduO1xuICAgIH0sIFt2YWx1ZSwgdmlzaWJsZV0pO1xuICAgIHJldHVybiAoUmVhY3QuY3JlYXRlRWxlbWVudChUb29sdGlwLCBfX2Fzc2lnbih7IHBsYWNlbWVudDogXCJ0b3BcIiwgb3ZlcmxheTogdGlwRm9ybWF0dGVyKHZhbHVlKSwgb3ZlcmxheUlubmVyU3R5bGU6IHsgbWluSGVpZ2h0OiBcImF1dG9cIiB9LCByZWY6IHRvb2x0aXBSZWYsIHZpc2libGU6IHZpc2libGUgfSwgcmVzdFByb3BzKSwgY2hpbGRyZW4pKTtcbn07XG5leHBvcnQgdmFyIGhhbmRsZVJlbmRlciA9IGZ1bmN0aW9uIChub2RlLCBwcm9wcykge1xuICAgIHJldHVybiAoUmVhY3QuY3JlYXRlRWxlbWVudChIYW5kbGVUb29sdGlwLCB7IHZhbHVlOiBwcm9wcy52YWx1ZSwgdmlzaWJsZTogcHJvcHMuZHJhZ2dpbmcgfSwgbm9kZSkpO1xufTtcbnZhciBUb29sdGlwU2xpZGVyID0gZnVuY3Rpb24gKF9hKSB7XG4gICAgdmFyIHRpcEZvcm1hdHRlciA9IF9hLnRpcEZvcm1hdHRlciwgdGlwUHJvcHMgPSBfYS50aXBQcm9wcywgcHJvcHMgPSBfX3Jlc3QoX2EsIFtcInRpcEZvcm1hdHRlclwiLCBcInRpcFByb3BzXCJdKTtcbiAgICB2YXIgdGlwSGFuZGxlUmVuZGVyID0gZnVuY3Rpb24gKG5vZGUsIGhhbmRsZVByb3BzKSB7XG4gICAgICAgIHJldHVybiAoUmVhY3QuY3JlYXRlRWxlbWVudChIYW5kbGVUb29sdGlwLCBfX2Fzc2lnbih7IHZhbHVlOiBoYW5kbGVQcm9wcy52YWx1ZSwgdmlzaWJsZTogaGFuZGxlUHJvcHMuZHJhZ2dpbmcsIHRpcEZvcm1hdHRlcjogdGlwRm9ybWF0dGVyIH0sIHRpcFByb3BzKSwgbm9kZSkpO1xuICAgIH07XG4gICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoU2xpZGVyLCBfX2Fzc2lnbih7fSwgcHJvcHMsIHsgaGFuZGxlUmVuZGVyOiB0aXBIYW5kbGVSZW5kZXIgfSkpO1xufTtcbmV4cG9ydCBkZWZhdWx0IFRvb2x0aXBTbGlkZXI7XG4iLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9pbmRleC5jc3NcIjtcbiAgICAgIFxuICAgICAgXG5cbnZhciBvcHRpb25zID0ge307XG5cbm9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0gPSBzdHlsZVRhZ1RyYW5zZm9ybUZuO1xub3B0aW9ucy5zZXRBdHRyaWJ1dGVzID0gc2V0QXR0cmlidXRlcztcblxuICAgICAgb3B0aW9ucy5pbnNlcnQgPSBpbnNlcnRGbi5iaW5kKG51bGwsIFwiaGVhZFwiKTtcbiAgICBcbm9wdGlvbnMuZG9tQVBJID0gZG9tQVBJO1xub3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7XG5cbnZhciB1cGRhdGUgPSBBUEkoY29udGVudCwgb3B0aW9ucyk7XG5cblxuXG5leHBvcnQgKiBmcm9tIFwiISEuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vaW5kZXguY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiLyoqXG4gKiBSZWxhYmkgY29udHJvbHNcbiAqIEBtb2R1bGUgc3JjL3VpL0NvbnRyb2xzLmpzeDtcbiAqL1xuXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IHVzZUNhbGxiYWNrLCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcblxuaW1wb3J0IFNsaWRlciBmcm9tIFwicmMtc2xpZGVyXCI7XG5pbXBvcnQgVG9vbHRpcFNsaWRlciwgeyBoYW5kbGVSZW5kZXIgfSBmcm9tIFwiLi9Ub29sdGlwU2xpZGVyLnRzeFwiO1xuaW1wb3J0IFwicmMtc2xpZGVyL2Fzc2V0cy9pbmRleC5jc3NcIjtcblxuY29uc3QgV0FWRV9TSEFQRV9OQU1FUyA9IFtcInNpbmVcIiwgXCJ0cmlhbmdsZVwiLCBcInNhd1wiLCBcInNxdWFyZVwiXTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29udHJvbHMoeyByZWxhYmkgfSkge1xuICAvKipcbiAgICogSGFuZGxlIHVwZGF0aW5nIGEgc2xpZGVyXG4gICAqL1xuICBjb25zdCBvbkNoYW5nZSA9IHVzZUNhbGxiYWNrKFxuICAgICh0eXBlLCBpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICBpZiAodHlwZSA9PT0gXCJib3VuZFwiKSB7XG4gICAgICAgIHJlbGFiaS5ib3VuZHNbaW5kZXhdLmxldmVsID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gXCJmcmVxdWVuY3lcIikge1xuICAgICAgICByZWxhYmkud2F2ZXNbaW5kZXhdLmZyZXF1ZW5jeSA9IE1hdGguZXhwKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlID09PSBcInNoYXBlXCIpIHtcbiAgICAgICAgcmVsYWJpLndhdmVzW2luZGV4XS5zaGFwZSA9IFdBVkVfU0hBUEVfTkFNRVNbdmFsdWVdO1xuICAgICAgfVxuICAgIH0sXG4gICAgW3JlbGFiaV1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxDb250cm9sUm93PlxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5Cb3VuZHM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LmJvdW5kcy5tYXAoKGJvdW5kLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgYm91bmRfJHtpbmRleH1gfVxuICAgICAgICAgICAgICB0eXBlPVwiYm91bmRcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXstMX1cbiAgICAgICAgICAgICAgbWF4PXsxfVxuICAgICAgICAgICAgICBzdGVwPXswLjAxfVxuICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU9e2JvdW5kLmxldmVsfVxuICAgICAgICAgICAgICBjb2xvcj17Ym91bmQuY29sb3J9XG4gICAgICAgICAgICAgIHJldmVyc2VcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuXG4gICAgICA8Q29udHJvbEJveD5cbiAgICAgICAgPExhYmVsPldhdmUgc3BlZWRzPC9MYWJlbD5cbiAgICAgICAgPFNsaWRlclJvdz5cbiAgICAgICAgICB7cmVsYWJpPy53YXZlcy5tYXAoKHdhdmUsIGluZGV4KSA9PiAoXG4gICAgICAgICAgICA8Q29udHJvbFNsaWRlclxuICAgICAgICAgICAgICByZWw9e2BmcmVxdWVuY3lfJHtpbmRleH1gfVxuICAgICAgICAgICAgICB0eXBlPVwiZnJlcXVlbmN5XCJcbiAgICAgICAgICAgICAgaW5kZXg9e2luZGV4fVxuICAgICAgICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAgICAgICAgIG1pbj17LTJ9XG4gICAgICAgICAgICAgIG1heD17M31cbiAgICAgICAgICAgICAgc3RlcD17MC4wMDF9XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17TWF0aC5sb2cod2F2ZS5mcmVxdWVuY3kpfVxuICAgICAgICAgICAgICBjb2xvcj17XCIjOGE4XCJ9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICkpfVxuICAgICAgICA8L1NsaWRlclJvdz5cbiAgICAgIDwvQ29udHJvbEJveD5cblxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5XYXZlIHNoYXBlczwvTGFiZWw+XG4gICAgICAgIDxTbGlkZXJSb3c+XG4gICAgICAgICAge3JlbGFiaT8ud2F2ZXMubWFwKCh3YXZlLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgc2hhcGVfJHtpbmRleH1gfVxuICAgICAgICAgICAgICB0eXBlPVwic2hhcGVcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXswfVxuICAgICAgICAgICAgICBtYXg9ezN9XG4gICAgICAgICAgICAgIHN0ZXA9ezF9XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17V0FWRV9TSEFQRV9OQU1FUy5pbmRleE9mKHdhdmUuc2hhcGUpfVxuICAgICAgICAgICAgICBjb2xvcj17XCIjOTk4XCJ9XG4gICAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBXQVZFX1NIQVBFX05BTUVTW3ZhbHVlXX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuICAgIDwvQ29udHJvbFJvdz5cbiAgKTtcbn1cblxuLyoqXG4gKiBVSSBFbGVtZW50c1xuICovXG5jb25zdCBDb250cm9sUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjdGlvbjogXCJyb3dcIixcbiAgICAgIG1hcmdpblRvcDogXCIxcmVtXCIsXG4gICAgfX1cbiAgPlxuICAgIHtjaGlsZHJlbn1cbiAgPC9kaXY+XG4pO1xuXG5jb25zdCBDb250cm9sQm94ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIG1hcmdpbkxlZnQ6IFwiMXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgU2xpZGVyUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjaXRvbjogXCJyb3dcIixcbiAgICAgIGhlaWdodDogXCIxMHJlbVwiLFxuICAgICAgbWFyZ2luVG9wOiBcIjAuNXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgTGFiZWwgPSAoeyBjaGlsZHJlbiB9KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgZm9udFNpemU6IFwiMC43NXJlbVwiIH19PntjaGlsZHJlbn08L2Rpdj5cbik7XG5cbmNvbnN0IENvbnRyb2xTbGlkZXIgPSAoe1xuICB0eXBlLFxuICBpbmRleCxcbiAgbWluLFxuICBtYXgsXG4gIHN0ZXAsXG4gIHJldmVyc2UsXG4gIGRlZmF1bHRWYWx1ZSxcbiAgY29sb3IsXG4gIG9uQ2hhbmdlLFxuICB0aXBGb3JtYXR0ZXIsXG59KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgbWFyZ2luUmlnaHQ6IFwiMC41cmVtXCIgfX0+XG4gICAgPFRvb2x0aXBTbGlkZXJcbiAgICAgIHZlcnRpY2FsXG4gICAgICBtaW49e21pbn1cbiAgICAgIG1heD17bWF4fVxuICAgICAgc3RlcD17c3RlcH1cbiAgICAgIHJldmVyc2U9e3JldmVyc2V9XG4gICAgICBkZWZhdWx0VmFsdWU9e2RlZmF1bHRWYWx1ZX1cbiAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZSh0eXBlLCBpbmRleCl9XG4gICAgICBoYW5kbGVTdHlsZT17e1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9yLFxuICAgICAgICBib3JkZXJDb2xvcjogY29sb3IsXG4gICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICB9fVxuICAgICAgdHJhY2tTdHlsZT17eyBiYWNrZ3JvdW5kQ29sb3I6IFwiIzg4OFwiLCB3aWR0aDogXCIycHhcIiB9fVxuICAgICAgcmFpbFN0eWxlPXt7IGJhY2tncm91bmRDb2xvcjogXCIjODg4XCIsIHdpZHRoOiBcIjJweFwiIH19XG4gICAgICB0aXBGb3JtYXR0ZXI9e3RpcEZvcm1hdHRlciB8fCAoKHZhbHVlKSA9PiB2YWx1ZSl9XG4gICAgLz5cbiAgPC9kaXY+XG4pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBSZWxhYmkgZnJvbSBcIi4uL3JlbGFiaVwiO1xuaW1wb3J0IHsgS2FsaW1iYSwgRHJ1bXMgfSBmcm9tIFwiLi4vbGliL2luc3RydW1lbnRzXCI7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSBcIi4vQ29udHJvbHMuanN4XCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFwcCgpIHtcbiAgY29uc3QgW3JlbGFiaSwgc2V0UmVsYWJpXSA9IHVzZVN0YXRlKCk7XG4gIGNvbnN0IHJlbGFiaVJlZiA9IHVzZVJlZigpO1xuXG4gIC8qKlxuICAgKiBJbnN0YW50aWF0ZSB0aGUgUmVsYWJpIGdlbmVyYXRvclxuICAgKi9cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXJlbGFiaSkge1xuICAgICAgY29uc3QgcmVsYWJpR2VuZXJhdG9yID0gbmV3IFJlbGFiaSh7XG4gICAgICAgIHdhdmVzOiBbXG4gICAgICAgICAgeyBzaGFwZTogXCJzaW5lXCIsIGZyZXF1ZW5jeTogMC43NSB9LFxuICAgICAgICAgIHsgc2hhcGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuMCB9LFxuICAgICAgICAgIHsgc2hhcGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuNjE3IH0sXG4gICAgICAgICAgeyBzaGFwZTogXCJzaW5lXCIsIGZyZXF1ZW5jeTogMy4xNDEgfSxcbiAgICAgICAgXSxcbiAgICAgICAgYm91bmRzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IC0wLjc1LFxuICAgICAgICAgICAgY29sb3I6IFwiI2YzM1wiLFxuICAgICAgICAgICAgc291bmRzOiBbXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogRHJ1bXMsIGluZGV4OiAwIH0sXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogRHJ1bXMsIGluZGV4OiAxIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IDAuNzUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjgzXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDIgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDMgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogLTAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjM2I4XCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6IDQ0MCB9LFxuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogKDQ0MCAqIDMpIC8gMiB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxldmVsOiAwLjI1LFxuICAgICAgICAgICAgY29sb3I6IFwiIzM2ZlwiLFxuICAgICAgICAgICAgc291bmRzOiBbXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogNikgLyA1IH0sXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogNikgLyA3IH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICAgIHJlbGFiaUdlbmVyYXRvci5zdGFydCgpO1xuICAgICAgc2V0UmVsYWJpKHJlbGFiaUdlbmVyYXRvcik7XG4gICAgfVxuICB9LCBbcmVsYWJpXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAocmVsYWJpICYmIHJlbGFiaVJlZi5jdXJyZW50KSB7XG4gICAgICByZWxhYmkuY2FudmFzLmFwcGVuZENhbnZhcyhyZWxhYmlSZWYuY3VycmVudCk7XG4gICAgfVxuICB9LCBbcmVsYWJpLCByZWxhYmlSZWYuY3VycmVudF0pO1xuXG4gIC8qKlxuICAgKiBSZW5kZXJcbiAgICovXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgc3R5bGU9e3tcbiAgICAgICAgaGVpZ2h0OiBcIjEwMCVcIixcbiAgICAgICAgd2lkdGg6IFwiMTAwJVwiLFxuICAgICAgICBwYWRkaW5nOiAwLFxuICAgICAgICBtYXJnaW46IDAsXG4gICAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgICBmbGV4RGlyZWN0aW9uOiBcImNvbHVtblwiLFxuICAgICAgICBqdXN0aWZ5Q29udGVudDogXCJjZW50ZXJcIixcbiAgICAgIH19XG4gICAgPlxuICAgICAgPGRpdiByZWY9e3JlbGFiaVJlZn0gLz5cbiAgICAgIDxDb250cm9scyByZWxhYmk9e3JlbGFiaX0gLz5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cbiIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgY3JlYXRlUm9vdCB9IGZyb20gXCJyZWFjdC1kb20vY2xpZW50XCI7XG5pbXBvcnQgeyByZXF1ZXN0QXVkaW9Db250ZXh0LCByYW5kcmFuZ2UgfSBmcm9tIFwiLi9saWIvdXRpbFwiO1xuXG5pbXBvcnQgQXBwIGZyb20gXCIuL3VpL0FwcC5qc3hcIjtcblxuZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcIiMxMTFcIjtcbmRvY3VtZW50LmJvZHkuc3R5bGUuY29sb3IgPSBcIiNmZmZcIjtcbmRvY3VtZW50LmJvZHkuc3R5bGUubWFyZ2luID0gMDtcbmRvY3VtZW50LmJvZHkuc3R5bGUucGFkZGluZyA9IDA7XG5kb2N1bWVudC5ib2R5LnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5mb250RmFtaWx5ID0gXCJIZWx2ZXRpY2EsIEFyaWFsXCI7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUubWFyZ2luID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuXG5yZXF1ZXN0QXVkaW9Db250ZXh0KCgpID0+IHtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29udGFpbmVyLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICBjb250YWluZXIuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbiAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBcIlwiO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGNvbnRhaW5lcik7XG4gIHJvb3QucmVuZGVyKDxBcHAgLz4pO1xufSk7XG4iXSwibmFtZXMiOlsiVG9uZSIsIlN0YXJ0QXVkaW9Db250ZXh0IiwiaXNJcGhvbmUiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJtYXRjaCIsImlzSXBhZCIsImlzQW5kcm9pZCIsImlzTW9iaWxlIiwiaXNEZXNrdG9wIiwiZG9jdW1lbnQiLCJib2R5IiwiY2xhc3NMaXN0IiwiYWRkIiwiYnJvd3NlciIsImNob2ljZSIsImEiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJsZW5ndGgiLCJtb2QiLCJuIiwibSIsInJhbmQiLCJyYW5kaW50IiwicmFuZHJhbmdlIiwiYiIsInJhbmRzaWduIiwicmFuZG51bGxzaWduIiwiciIsInJlcXVlc3RBdWRpb0NvbnRleHQiLCJmbiIsImNvbnRhaW5lciIsImNyZWF0ZUVsZW1lbnQiLCJidXR0b24iLCJpbm5lckhUTUwiLCJPYmplY3QiLCJhc3NpZ24iLCJzdHlsZSIsImRpc3BsYXkiLCJwb3NpdGlvbiIsIndpZHRoIiwiaGVpZ2h0IiwiekluZGV4IiwidG9wIiwibGVmdCIsImJhY2tncm91bmRDb2xvciIsInBhZGRpbmciLCJjb2xvciIsImZvbnRGYW1pbHkiLCJib3JkZXJSYWRpdXMiLCJ0cmFuc2Zvcm0iLCJ0ZXh0QWxpZ24iLCJsaW5lSGVpZ2h0IiwiY3Vyc29yIiwiYXBwZW5kQ2hpbGQiLCJzZXRDb250ZXh0IiwiY29udGV4dCIsIm9uIiwib25TdGFydGVkIiwiXyIsInJlbW92ZSIsIlJlbGFiaUNhbnZhcyIsIl9yZWYiLCJyZWxhYmkiLCJwYXJlbnQiLCJfY2xhc3NDYWxsQ2hlY2siLCJsYXN0RnJhbWUiLCJsYXN0QXBwZW5kVGltZSIsImxhc3RBcHBlbmRGcmFtZSIsInNwZWVkIiwidFplcm9PZmZzZXQiLCJhcHBlbmRDYW52YXMiLCJ2YWx1ZXMiLCJBcnJheSIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJmaWxsIiwibm90ZXMiLCJhcHBlbmQiLCJyZXNpemUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImNhbnZhcyIsImN0eCIsImdldENvbnRleHQiLCJfcmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiX3giLCJhcHBseSIsImFyZ3VtZW50cyIsInRvU3RyaW5nIiwiZnJhbWUiLCJfdGhpcyIsInBhaW50IiwiY2xlYXIiLCJjbGVhclJlY3QiLCJ0aW1lIiwiZmlsdGVyIiwiY29uY2F0Iiwic2xpY2UiLCJzb3J0IiwiZHJhd1JlbGFiaVdhdmUiLCJkcmF3Qm91bmRzIiwiZHJhd05vdGVzIiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJib3VuZHMiLCJfc3RlcCIsInMiLCJkb25lIiwiYm91bmQiLCJ5IiwiZ2V0V2F2ZUhlaWdodCIsImxldmVsIiwiYmVnaW5QYXRoIiwic2V0TGluZURhc2giLCJsaW5lV2lkdGgiLCJzdHJva2VTdHlsZSIsIm1vdmVUbyIsImxpbmVUbyIsInN0cm9rZSIsImVyciIsImUiLCJmIiwicG9pbnRDb3VudCIsImluZGV4IiwiZnJhbWVPZmZzZXQiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicG9pbnQiLCJfcG9pbnQiLCJfc2xpY2VkVG9BcnJheSIsInRpbWVPZmZzZXQiLCJ4IiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsIm5vdGUiLCJfbm90ZSIsImRpcmVjdGlvbiIsIm9wYWNpdHkiLCJhcmMiLCJQSSIsImZpbGxTdHlsZSIsImRlZmF1bHQiLCJUV09fUEkiLCJXQVZFX1NIQVBFUyIsInNpbmUiLCJjb3MiLCJ0cmlhbmdsZSIsImFicyIsInNxdWFyZSIsInNhdyIsIlJlbGFiaSIsIndhdmVzIiwidXBkYXRlVGltZSIsInN0ZXBzIiwic2hhcGUiLCJmcmVxdWVuY3kiLCJwcmV2aW91c1ZhbHVlIiwic3RhcnQiLCJjb25zb2xlIiwibG9nIiwic3RvcCIsImNsb2NrIiwiQ2xvY2siLCJnZW5lcmF0ZSIsInBsYXkiLCJkaXNwb3NlIiwid2F2ZUNvdW50Iiwic3RlcCIsInN0ZXBDb3VudCIsIndhdmUiLCJwdXNoIiwiYm91bmRzQ291bnQiLCJub3RlQ291bnQiLCJfdmFsdWVzJHN0ZXAiLCJ0cmlnZ2VyIiwic291bmRzIiwic291bmQiLCJpbnN0cnVtZW50IiwiY29tcHJlc3NvciIsIkNvbXByZXNzb3IiLCJnYWluIiwiR2FpbiIsImNvbm5lY3QiLCJ0b0Rlc3RpbmF0aW9uIiwib3V0cHV0IiwiUExBWUVSX0NPVU5UIiwiU2FtcGxlciIsInNhbXBsZXMiLCJ0b25hbCIsIm1hcCIsIl9yZWYyIiwic2FtcGxlIiwiX2V4dGVuZHMiLCJfb2JqZWN0RGVzdHJ1Y3R1cmluZ0VtcHR5IiwicGxheWVycyIsImkiLCJsb2NhdGlvbiIsImhyZWYiLCJwbGF5ZXIiLCJQbGF5ZXIiLCJ1cmwiLCJyZXRyaWdnZXIiLCJwbGF5YmFja1JhdGUiLCJvcHRpb25zIiwicm9vdCIsIkthbGltYmEiLCJEcnVtcyIsIlJlYWN0IiwidXNlQ2FsbGJhY2siLCJ1c2VSZWYiLCJTbGlkZXIiLCJUb29sdGlwU2xpZGVyIiwiaGFuZGxlUmVuZGVyIiwiV0FWRV9TSEFQRV9OQU1FUyIsIkNvbnRyb2xzIiwib25DaGFuZ2UiLCJ0eXBlIiwiZXhwIiwiQ29udHJvbFJvdyIsIkNvbnRyb2xCb3giLCJMYWJlbCIsIlNsaWRlclJvdyIsIkNvbnRyb2xTbGlkZXIiLCJyZWwiLCJtaW4iLCJtYXgiLCJkZWZhdWx0VmFsdWUiLCJyZXZlcnNlIiwiaW5kZXhPZiIsInRpcEZvcm1hdHRlciIsImNoaWxkcmVuIiwiZmxleERpcmVjdGlvbiIsIm1hcmdpblRvcCIsIl9yZWYzIiwibWFyZ2luTGVmdCIsIl9yZWY0IiwiZmxleERpcmVjaXRvbiIsIl9yZWY1IiwiZm9udFNpemUiLCJfcmVmNiIsIm1hcmdpblJpZ2h0IiwidmVydGljYWwiLCJoYW5kbGVTdHlsZSIsImJvcmRlckNvbG9yIiwidHJhY2tTdHlsZSIsInJhaWxTdHlsZSIsInVzZVN0YXRlIiwidXNlRWZmZWN0IiwiQXBwIiwiX3VzZVN0YXRlIiwiX3VzZVN0YXRlMiIsInNldFJlbGFiaSIsInJlbGFiaVJlZiIsInJlbGFiaUdlbmVyYXRvciIsImN1cnJlbnQiLCJtYXJnaW4iLCJqdXN0aWZ5Q29udGVudCIsInJlZiIsImNyZWF0ZVJvb3QiLCJwYXJlbnROb2RlIiwicmVuZGVyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///905\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjMxLmpzIiwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUFBLE1BQU0sQ0FBQ0MsdUJBQXVCLEdBQUcsS0FBSztBQUV0QyxDQUFDLFVBQVVDLElBQUksRUFBRUMsT0FBTyxFQUFFO0VBQ3hCLElBQUksSUFBMEMsRUFBRTtJQUM5Q0MsaUNBQU8sRUFBRSxvQ0FBRUQsT0FBTztBQUFBO0FBQUE7QUFBQSxrR0FBQztFQUNyQixDQUFDLE1BQU0sRUFJTjtBQUNILENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWTtFQUNuQjtBQUNGO0FBQ0E7RUFDRSxJQUFJTSxpQkFBaUIsR0FBRztJQUN0QjtBQUNKO0FBQ0E7QUFDQTtJQUNJQyxPQUFPLEVBQUUsSUFBSTtJQUNiO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7SUFDSUMsYUFBYSxFQUFFLEVBQUU7SUFDakI7QUFDSjtBQUNBO0FBQ0E7QUFDQTtJQUNJQyxVQUFVLEVBQUU7RUFDZCxDQUFDOztFQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDRUgsaUJBQWlCLENBQUNJLFVBQVUsR0FBRyxVQUFVQyxHQUFHLEVBQUU7SUFDNUNMLGlCQUFpQixDQUFDQyxPQUFPLEdBQUdJLEdBQUc7SUFDL0IsT0FBT0wsaUJBQWlCO0VBQzFCLENBQUM7O0VBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtFQUNFQSxpQkFBaUIsQ0FBQ00sRUFBRSxHQUFHLFVBQVVDLE9BQU8sRUFBRTtJQUN4QyxJQUFJQyxLQUFLLENBQUNDLE9BQU8sQ0FBQ0YsT0FBTyxDQUFDLElBQUtHLFFBQVEsSUFBSUgsT0FBTyxZQUFZRyxRQUFTLEVBQUU7TUFDdkUsS0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdKLE9BQU8sQ0FBQ0ssTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtRQUN2Q1gsaUJBQWlCLENBQUNNLEVBQUUsQ0FBQ0MsT0FBTyxDQUFDSSxDQUFDLENBQUMsQ0FBQztNQUNsQztJQUNGLENBQUMsTUFBTSxJQUFJLE9BQU9KLE9BQU8sS0FBSyxRQUFRLEVBQUU7TUFDdENQLGlCQUFpQixDQUFDTSxFQUFFLENBQUNPLFFBQVEsQ0FBQ0MsZ0JBQWdCLENBQUNQLE9BQU8sQ0FBQyxDQUFDO0lBQzFELENBQUMsTUFBTSxJQUFJQSxPQUFPLENBQUNRLE1BQU0sSUFBSSxPQUFPUixPQUFPLENBQUNTLE9BQU8sS0FBSyxVQUFVLEVBQUU7TUFDbEVoQixpQkFBaUIsQ0FBQ00sRUFBRSxDQUFDQyxPQUFPLENBQUNTLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDekMsQ0FBQyxNQUFNLElBQUlDLE9BQU8sSUFBSVYsT0FBTyxZQUFZVSxPQUFPLEVBQUU7TUFDaEQ7TUFDQSxJQUFJQyxHQUFHLEdBQUcsSUFBSUMsV0FBVyxDQUFDWixPQUFPLEVBQUVhLEtBQUssQ0FBQztNQUN6Q3BCLGlCQUFpQixDQUFDRSxhQUFhLENBQUNtQixJQUFJLENBQUNILEdBQUcsQ0FBQztJQUMzQztJQUNBLE9BQU9sQixpQkFBaUI7RUFDMUIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0VBQ0VBLGlCQUFpQixDQUFDc0IsU0FBUyxHQUFHLFVBQVVDLEVBQUUsRUFBRTtJQUMxQztJQUNBLElBQUl2QixpQkFBaUIsQ0FBQ3dCLFNBQVMsQ0FBQyxDQUFDLEVBQUU7TUFDakNELEVBQUUsQ0FBQyxDQUFDO0lBQ04sQ0FBQyxNQUFNO01BQ0x2QixpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDa0IsSUFBSSxDQUFDRSxFQUFFLENBQUM7SUFDdkM7SUFDQSxPQUFPdkIsaUJBQWlCO0VBQzFCLENBQUM7O0VBRUQ7QUFDRjtBQUNBO0FBQ0E7RUFDRUEsaUJBQWlCLENBQUN3QixTQUFTLEdBQUcsWUFBWTtJQUN4QyxPQUNHeEIsaUJBQWlCLENBQUNDLE9BQU8sS0FBSyxJQUFJLElBQ2pDRCxpQkFBaUIsQ0FBQ0MsT0FBTyxDQUFDd0IsS0FBSyxLQUFLLFNBQVMsSUFDL0NsQyxNQUFNLENBQUNDLHVCQUF1QjtFQUVsQyxDQUFDOztFQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7RUFDRSxJQUFJMkIsV0FBVyxHQUFHLFNBQWRBLFdBQVdBLENBQWFaLE9BQU8sRUFBRTtJQUNuQyxJQUFJLENBQUNtQixRQUFRLEdBQUcsS0FBSztJQUVyQixJQUFJLENBQUNDLFFBQVEsR0FBR3BCLE9BQU87SUFFdkIsSUFBSSxDQUFDcUIsV0FBVyxHQUFHLElBQUksQ0FBQ0MsTUFBTSxDQUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3pDLElBQUksQ0FBQ0MsVUFBVSxHQUFHLElBQUksQ0FBQ0MsTUFBTSxDQUFDRixJQUFJLENBQUMsSUFBSSxDQUFDO0lBRXhDdkIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQ0wsV0FBVyxDQUFDO0lBQ3ZEckIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQ0YsVUFBVSxDQUFDO0lBQ3JEeEIsT0FBTyxDQUFDMEIsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQ0YsVUFBVSxDQUFDO0VBQ3RELENBQUM7O0VBRUQ7QUFDRjtBQUNBO0VBQ0VaLFdBQVcsQ0FBQ2UsU0FBUyxDQUFDTCxNQUFNLEdBQUcsVUFBVU0sQ0FBQyxFQUFFO0lBQzFDLElBQUksQ0FBQ1QsUUFBUSxHQUFHLElBQUk7RUFDdEIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7RUFDRVAsV0FBVyxDQUFDZSxTQUFTLENBQUNGLE1BQU0sR0FBRyxVQUFVRyxDQUFDLEVBQUU7SUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQ1QsUUFBUSxFQUFFO01BQ2xCTixLQUFLLENBQUMsQ0FBQztJQUNUO0lBQ0EsSUFBSSxDQUFDTSxRQUFRLEdBQUcsS0FBSztFQUN2QixDQUFDOztFQUVEO0FBQ0Y7QUFDQTtFQUNFUCxXQUFXLENBQUNlLFNBQVMsQ0FBQ0UsT0FBTyxHQUFHLFlBQVk7SUFDMUMsSUFBSSxDQUFDVCxRQUFRLENBQUNVLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUNULFdBQVcsQ0FBQztJQUNoRSxJQUFJLENBQUNELFFBQVEsQ0FBQ1UsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQ04sVUFBVSxDQUFDO0lBQzlELElBQUksQ0FBQ0osUUFBUSxDQUFDVSxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDTixVQUFVLENBQUM7SUFDN0QsSUFBSSxDQUFDSCxXQUFXLEdBQUcsSUFBSTtJQUN2QixJQUFJLENBQUNHLFVBQVUsR0FBRyxJQUFJO0lBQ3RCLElBQUksQ0FBQ0osUUFBUSxHQUFHLElBQUk7RUFDdEIsQ0FBQzs7RUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0VBQ0UsU0FBU1AsS0FBS0EsQ0FBQSxFQUFHO0lBQ2YsSUFBSTtNQUNGO01BQ0EsSUFBSXBCLGlCQUFpQixDQUFDQyxPQUFPLElBQUksQ0FBQ0QsaUJBQWlCLENBQUN3QixTQUFTLENBQUMsQ0FBQyxFQUFFO1FBQy9ELElBQUljLEdBQUcsR0FBR3RDLGlCQUFpQixDQUFDQyxPQUFPLENBQUNzQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3RELElBQUlDLE1BQU0sR0FBR3hDLGlCQUFpQixDQUFDQyxPQUFPLENBQUN3QyxVQUFVLENBQUMsQ0FBQztRQUNuREQsTUFBTSxDQUFDRSxJQUFJLENBQUNDLEtBQUssR0FBRyxDQUFDO1FBQ3JCTCxHQUFHLENBQUNNLE9BQU8sQ0FBQ0osTUFBTSxDQUFDO1FBQ25CQSxNQUFNLENBQUNJLE9BQU8sQ0FBQzVDLGlCQUFpQixDQUFDQyxPQUFPLENBQUM0QyxXQUFXLENBQUM7UUFDckQsSUFBSUMsR0FBRyxHQUFHOUMsaUJBQWlCLENBQUNDLE9BQU8sQ0FBQzhDLFdBQVc7UUFDL0NULEdBQUcsQ0FBQ1UsS0FBSyxDQUFDRixHQUFHLENBQUM7UUFDZFIsR0FBRyxDQUFDVyxJQUFJLENBQUNILEdBQUcsR0FBRyxHQUFHLENBQUM7TUFDckI7O01BRUE7TUFDQSxJQUFJOUMsaUJBQWlCLENBQUNFLGFBQWEsRUFBRTtRQUNuQyxLQUFLLElBQUlTLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR1gsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1UsTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtVQUMvRFgsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1MsQ0FBQyxDQUFDLENBQUN5QixPQUFPLENBQUMsQ0FBQztRQUM5QztRQUNBcEMsaUJBQWlCLENBQUNFLGFBQWEsR0FBRyxJQUFJO01BQ3hDOztNQUVBO01BQ0EsSUFBSUYsaUJBQWlCLENBQUNHLFVBQVUsRUFBRTtRQUNoQyxLQUFLLElBQUkrQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdsRCxpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDUyxNQUFNLEVBQUVzQyxDQUFDLEVBQUUsRUFBRTtVQUM1RGxELGlCQUFpQixDQUFDRyxVQUFVLENBQUMrQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DO1FBQ0FsRCxpQkFBaUIsQ0FBQ0csVUFBVSxHQUFHLElBQUk7TUFDckM7TUFFQVosTUFBTSxDQUFDQyx1QkFBdUIsR0FBRyxJQUFJO0lBQ3ZDLENBQUMsQ0FBQyxPQUFPMkQsS0FBSyxFQUFFO01BQ2Q7SUFBQTtFQUVKO0VBRUEsT0FBT25ELGlCQUFpQjtBQUMxQixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3N0YXJ0QXVkaW9Db250ZXh0LmpzPzZlYmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgU3RhcnRBdWRpb0NvbnRleHQuanNcbiAqICBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqICBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiAgQGNvcHlyaWdodCAyMDE2IFlvdGFtIE1hbm5cbiAqL1xuXG53aW5kb3cuX19hdWRpb19jb250ZXh0X3N0YXJ0ZWQgPSBmYWxzZTtcblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuU3RhcnRBdWRpb0NvbnRleHQgPSBmYWN0b3J5KCk7XG4gIH1cbn0pKHRoaXMsIGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIFRoZSBTdGFydEF1ZGlvQ29udGV4dCBvYmplY3RcbiAgICovXG4gIHZhciBTdGFydEF1ZGlvQ29udGV4dCA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gY29udGV4dCBwYXNzZWQgaW4gYnkgdGhlIHVzZXJcbiAgICAgKiBAdHlwZSB7QXVkaW9Db250ZXh0fVxuICAgICAqL1xuICAgIGNvbnRleHQ6IG51bGwsXG4gICAgLyoqXG4gICAgICogVGhlIFRhcExpc3RlbmVycyBib3VuZCB0byB0aGUgZWxlbWVudHNcbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdGFwTGlzdGVuZXJzOiBbXSxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN0YXJ0ZWQ6IFtdLFxuICB9O1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbnRleHRcbiAgICogQHBhcmFtIHtBdWRpb0NvbnRleHR9IGN0eFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0ID0gZnVuY3Rpb24gKGN0eCkge1xuICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQgPSBjdHg7XG4gICAgcmV0dXJuIFN0YXJ0QXVkaW9Db250ZXh0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSB0YXAgbGlzdGVuZXIgdG8gdGhlIGF1ZGlvIGNvbnRleHRcbiAgICogQHBhcmFtICB7QXJyYXl8RWxlbWVudHxTdHJpbmd8alF1ZXJ5fSBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtTdGFydEF1ZGlvQ29udGV4dH1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbGVtZW50KSB8fCAoTm9kZUxpc3QgJiYgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGVsZW1lbnRbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudCkpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudC5qcXVlcnkgJiYgdHlwZW9mIGVsZW1lbnQudG9BcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihlbGVtZW50LnRvQXJyYXkoKSk7XG4gICAgfSBlbHNlIGlmIChFbGVtZW50ICYmIGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAvL2lmIGl0J3MgYW4gZWxlbWVudCwgY3JlYXRlIGEgVGFwTGlzdGVuZXJcbiAgICAgIHZhciB0YXAgPSBuZXcgVGFwTGlzdGVuZXIoZWxlbWVudCwgb25UYXApO1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5wdXNoKHRhcCk7XG4gICAgfVxuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQmluZCBhIGNhbGxiYWNrIHRvIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICogQHJldHVybiB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICAvL2lmIGl0J3MgYWxyZWFkeSBzdGFydGVkLCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKSB7XG4gICAgICBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkLnB1c2goY2IpO1xuICAgIH1cbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBpcyBzdGFydGVkXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmXG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuc3RhdGUgPT09IFwicnVubmluZ1wiKSB8fFxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogQGNsYXNzICBMaXN0ZW5zIGZvciBub24tZHJhZ2dpbmcgdGFwIGVuZHMgb24gdGhlIGdpdmVuIGVsZW1lbnRcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdmFyIFRhcExpc3RlbmVyID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSB0aGlzLl9tb3ZlZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IHRoaXMuX2VuZGVkLmJpbmQodGhpcyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGRyYWcgbW92ZSBldmVudFxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9tb3ZlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdGhpcy5fZHJhZ2dlZCA9IHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIHRhcCBlbmRlZCBsaXN0ZW5lclxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9lbmRlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKCF0aGlzLl9kcmFnZ2VkKSB7XG4gICAgICBvblRhcCgpO1xuICAgIH1cbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBhbGwgdGhlIGJvdW5kIGV2ZW50c1xuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX2JpbmRlZE1vdmUpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSBudWxsO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IG51bGw7XG4gICAgdGhpcy5fZWxlbWVudCA9IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEludm9rZWQgdGhlIGZpcnN0IHRpbWUgb2YgdGhlIGVsZW1lbnRzIGlzIHRhcHBlZC5cbiAgICogQ3JlYXRlcyBhIHNpbGVudCBvc2NpbGxhdG9yIHdoZW4gYSBub24tZHJhZ2dpbmcgdG91Y2hlbmRcbiAgICogZXZlbnQgaGFzIGJlZW4gdHJpZ2dlcmVkLlxuICAgKi9cbiAgZnVuY3Rpb24gb25UYXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQgd2l0aCBhIHNpbGVudCBvc2NpbGxhdG9yXG4gICAgICBpZiAoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dCAmJiAhU3RhcnRBdWRpb0NvbnRleHQuaXNTdGFydGVkKCkpIHtcbiAgICAgICAgdmFyIG9zYyA9IFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIHNpbGVudC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgb3NjLmNvbm5lY3Qoc2lsZW50KTtcbiAgICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHZhciBub3cgPSBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICBvc2Muc3RhcnQobm93KTtcbiAgICAgICAgb3NjLnN0b3Aobm93ICsgMC41KTtcbiAgICAgIH1cblxuICAgICAgLy9kaXNwb3NlIGFsbCB0aGUgdGFwIGxpc3RlbmVyc1xuICAgICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVyc1tpXS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vdGhlIG9uc3RhcnRlZCBjYWxsYmFja3NcbiAgICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWRbal0oKTtcbiAgICAgICAgfVxuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy9cbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KTtcbiJdLCJuYW1lcyI6WyJ3aW5kb3ciLCJfX2F1ZGlvX2NvbnRleHRfc3RhcnRlZCIsInJvb3QiLCJmYWN0b3J5IiwiZGVmaW5lIiwiYW1kIiwibW9kdWxlIiwiX3R5cGVvZiIsImV4cG9ydHMiLCJTdGFydEF1ZGlvQ29udGV4dCIsImNvbnRleHQiLCJfdGFwTGlzdGVuZXJzIiwiX29uU3RhcnRlZCIsInNldENvbnRleHQiLCJjdHgiLCJvbiIsImVsZW1lbnQiLCJBcnJheSIsImlzQXJyYXkiLCJOb2RlTGlzdCIsImkiLCJsZW5ndGgiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJqcXVlcnkiLCJ0b0FycmF5IiwiRWxlbWVudCIsInRhcCIsIlRhcExpc3RlbmVyIiwib25UYXAiLCJwdXNoIiwib25TdGFydGVkIiwiY2IiLCJpc1N0YXJ0ZWQiLCJzdGF0ZSIsIl9kcmFnZ2VkIiwiX2VsZW1lbnQiLCJfYmluZGVkTW92ZSIsIl9tb3ZlZCIsImJpbmQiLCJfYmluZGVkRW5kIiwiX2VuZGVkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByb3RvdHlwZSIsImUiLCJkaXNwb3NlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm9zYyIsImNyZWF0ZU9zY2lsbGF0b3IiLCJzaWxlbnQiLCJjcmVhdGVHYWluIiwiZ2FpbiIsInZhbHVlIiwiY29ubmVjdCIsImRlc3RpbmF0aW9uIiwibm93IiwiY3VycmVudFRpbWUiLCJzdGFydCIsInN0b3AiLCJqIiwiZXJyb3IiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///631\n')},184:(module,exports)=>{eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\tvar nativeCodeString = '[native code]';\n\n\tfunction classNames() {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg)) {\n\t\t\t\tif (arg.length) {\n\t\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\t\tif (inner) {\n\t\t\t\t\t\tclasses.push(inner);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\t\t\tclasses.push(arg.toString());\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif ( true && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (true) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n\t\t\treturn classNames;\n\t\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n}());\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTg0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixzQkFBc0I7QUFDeEM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUssS0FBNkI7QUFDbEM7QUFDQTtBQUNBLEdBQUcsU0FBUyxJQUE0RTtBQUN4RjtBQUNBLEVBQUUsaUNBQXFCLEVBQUUsbUNBQUU7QUFDM0I7QUFDQSxHQUFHO0FBQUEsa0dBQUM7QUFDSixHQUFHLEtBQUssRUFFTjtBQUNGLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvY2xhc3NuYW1lcy9pbmRleC5qcz80ZDI2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuXHRDb3B5cmlnaHQgKGMpIDIwMTggSmVkIFdhdHNvbi5cblx0TGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlIChNSVQpLCBzZWVcblx0aHR0cDovL2plZHdhdHNvbi5naXRodWIuaW8vY2xhc3NuYW1lc1xuKi9cbi8qIGdsb2JhbCBkZWZpbmUgKi9cblxuKGZ1bmN0aW9uICgpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBoYXNPd24gPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblx0dmFyIG5hdGl2ZUNvZGVTdHJpbmcgPSAnW25hdGl2ZSBjb2RlXSc7XG5cblx0ZnVuY3Rpb24gY2xhc3NOYW1lcygpIHtcblx0XHR2YXIgY2xhc3NlcyA9IFtdO1xuXG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBhcmcgPSBhcmd1bWVudHNbaV07XG5cdFx0XHRpZiAoIWFyZykgY29udGludWU7XG5cblx0XHRcdHZhciBhcmdUeXBlID0gdHlwZW9mIGFyZztcblxuXHRcdFx0aWYgKGFyZ1R5cGUgPT09ICdzdHJpbmcnIHx8IGFyZ1R5cGUgPT09ICdudW1iZXInKSB7XG5cdFx0XHRcdGNsYXNzZXMucHVzaChhcmcpO1xuXHRcdFx0fSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGFyZykpIHtcblx0XHRcdFx0aWYgKGFyZy5sZW5ndGgpIHtcblx0XHRcdFx0XHR2YXIgaW5uZXIgPSBjbGFzc05hbWVzLmFwcGx5KG51bGwsIGFyZyk7XG5cdFx0XHRcdFx0aWYgKGlubmVyKSB7XG5cdFx0XHRcdFx0XHRjbGFzc2VzLnB1c2goaW5uZXIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmIChhcmdUeXBlID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRpZiAoYXJnLnRvU3RyaW5nICE9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nICYmICFhcmcudG9TdHJpbmcudG9TdHJpbmcoKS5pbmNsdWRlcygnW25hdGl2ZSBjb2RlXScpKSB7XG5cdFx0XHRcdFx0Y2xhc3Nlcy5wdXNoKGFyZy50b1N0cmluZygpKTtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZvciAodmFyIGtleSBpbiBhcmcpIHtcblx0XHRcdFx0XHRpZiAoaGFzT3duLmNhbGwoYXJnLCBrZXkpICYmIGFyZ1trZXldKSB7XG5cdFx0XHRcdFx0XHRjbGFzc2VzLnB1c2goa2V5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gY2xhc3Nlcy5qb2luKCcgJyk7XG5cdH1cblxuXHRpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcblx0XHRjbGFzc05hbWVzLmRlZmF1bHQgPSBjbGFzc05hbWVzO1xuXHRcdG1vZHVsZS5leHBvcnRzID0gY2xhc3NOYW1lcztcblx0fSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkZWZpbmUuYW1kID09PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gcmVnaXN0ZXIgYXMgJ2NsYXNzbmFtZXMnLCBjb25zaXN0ZW50IHdpdGggbnBtIHBhY2thZ2UgbmFtZVxuXHRcdGRlZmluZSgnY2xhc3NuYW1lcycsIFtdLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gY2xhc3NOYW1lcztcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHR3aW5kb3cuY2xhc3NOYW1lcyA9IGNsYXNzTmFtZXM7XG5cdH1cbn0oKSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///184\n")},687:(module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(537);\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(645);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ".rc-slider {\\n position: relative;\\n width: 100%;\\n height: 14px;\\n padding: 5px 0;\\n border-radius: 6px;\\n touch-action: none;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-rail {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background-color: #e9e9e9;\\n border-radius: 6px;\\n}\\n.rc-slider-track {\\n position: absolute;\\n height: 4px;\\n background-color: #abe2fb;\\n border-radius: 6px;\\n}\\n.rc-slider-handle {\\n position: absolute;\\n width: 14px;\\n height: 14px;\\n margin-top: -5px;\\n background-color: #fff;\\n border: solid 2px #96dbfa;\\n border-radius: 50%;\\n cursor: pointer;\\n cursor: -webkit-grab;\\n cursor: grab;\\n opacity: 0.8;\\n touch-action: pan-x;\\n}\\n.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {\\n border-color: #57c5f7;\\n box-shadow: 0 0 0 5px #96dbfa;\\n}\\n.rc-slider-handle:focus {\\n outline: none;\\n box-shadow: none;\\n}\\n.rc-slider-handle:focus-visible {\\n border-color: #2db7f5;\\n box-shadow: 0 0 0 3px #96dbfa;\\n}\\n.rc-slider-handle-click-focused:focus {\\n border-color: #96dbfa;\\n box-shadow: unset;\\n}\\n.rc-slider-handle:hover {\\n border-color: #57c5f7;\\n}\\n.rc-slider-handle:active {\\n border-color: #57c5f7;\\n box-shadow: 0 0 5px #57c5f7;\\n cursor: -webkit-grabbing;\\n cursor: grabbing;\\n}\\n.rc-slider-mark {\\n position: absolute;\\n top: 18px;\\n left: 0;\\n width: 100%;\\n font-size: 12px;\\n}\\n.rc-slider-mark-text {\\n position: absolute;\\n display: inline-block;\\n color: #999;\\n text-align: center;\\n vertical-align: middle;\\n cursor: pointer;\\n}\\n.rc-slider-mark-text-active {\\n color: #666;\\n}\\n.rc-slider-step {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background: transparent;\\n pointer-events: none;\\n}\\n.rc-slider-dot {\\n position: absolute;\\n bottom: -2px;\\n width: 8px;\\n height: 8px;\\n vertical-align: middle;\\n background-color: #fff;\\n border: 2px solid #e9e9e9;\\n border-radius: 50%;\\n cursor: pointer;\\n}\\n.rc-slider-dot-active {\\n border-color: #96dbfa;\\n}\\n.rc-slider-dot-reverse {\\n margin-right: -4px;\\n}\\n.rc-slider-disabled {\\n background-color: #e9e9e9;\\n}\\n.rc-slider-disabled .rc-slider-track {\\n background-color: #ccc;\\n}\\n.rc-slider-disabled .rc-slider-handle,\\n.rc-slider-disabled .rc-slider-dot {\\n background-color: #fff;\\n border-color: #ccc;\\n box-shadow: none;\\n cursor: not-allowed;\\n}\\n.rc-slider-disabled .rc-slider-mark-text,\\n.rc-slider-disabled .rc-slider-dot {\\n cursor: not-allowed !important;\\n}\\n.rc-slider-vertical {\\n width: 14px;\\n height: 100%;\\n padding: 0 5px;\\n}\\n.rc-slider-vertical .rc-slider-rail {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-track {\\n bottom: 0;\\n left: 5px;\\n width: 4px;\\n}\\n.rc-slider-vertical .rc-slider-handle {\\n margin-top: 0;\\n margin-left: -5px;\\n touch-action: pan-y;\\n}\\n.rc-slider-vertical .rc-slider-mark {\\n top: 0;\\n left: 18px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-step {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-dot {\\n margin-left: -2px;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,\\n.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {\\n animation-name: rcSliderTooltipZoomDownIn;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {\\n animation-name: rcSliderTooltipZoomDownOut;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n transform: scale(0, 0);\\n animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);\\n}\\n@keyframes rcSliderTooltipZoomDownIn {\\n 0% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n 100% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n}\\n@keyframes rcSliderTooltipZoomDownOut {\\n 0% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n 100% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n}\\n.rc-slider-tooltip {\\n position: absolute;\\n top: -9999px;\\n left: -9999px;\\n visibility: visible;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip-hidden {\\n display: none;\\n}\\n.rc-slider-tooltip-placement-top {\\n padding: 4px 0 8px 0;\\n}\\n.rc-slider-tooltip-inner {\\n min-width: 24px;\\n height: 24px;\\n padding: 6px 2px;\\n color: #fff;\\n font-size: 12px;\\n line-height: 1;\\n text-align: center;\\n text-decoration: none;\\n background-color: #6c6c6c;\\n border-radius: 6px;\\n box-shadow: 0 0 4px #d9d9d9;\\n}\\n.rc-slider-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {\\n bottom: 4px;\\n left: 50%;\\n margin-left: -4px;\\n border-width: 4px 4px 0;\\n border-top-color: #6c6c6c;\\n}\\n", "",{"version":3,"sources":["webpack://./node_modules/rc-slider/assets/index.css"],"names":[],"mappings":"AAAA;EACE,kBAAkB;EAClB,WAAW;EACX,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,kBAAkB;EAClB,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,WAAW;EACX,yBAAyB;EACzB,kBAAkB;AACpB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,yBAAyB;EACzB,kBAAkB;AACpB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,YAAY;EACZ,gBAAgB;EAChB,sBAAsB;EACtB,yBAAyB;EACzB,kBAAkB;EAClB,eAAe;EACf,oBAAoB;EACpB,YAAY;EACZ,YAAY;EACZ,mBAAmB;AACrB;AACA;EACE,qBAAqB;EACrB,6BAA6B;AAC/B;AACA;EACE,aAAa;EACb,gBAAgB;AAClB;AACA;EACE,qBAAqB;EACrB,6BAA6B;AAC/B;AACA;EACE,qBAAqB;EACrB,iBAAiB;AACnB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,qBAAqB;EACrB,2BAA2B;EAC3B,wBAAwB;EACxB,gBAAgB;AAClB;AACA;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,WAAW;EACX,eAAe;AACjB;AACA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,WAAW;EACX,kBAAkB;EAClB,sBAAsB;EACtB,eAAe;AACjB;AACA;EACE,WAAW;AACb;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,WAAW;EACX,uBAAuB;EACvB,oBAAoB;AACtB;AACA;EACE,kBAAkB;EAClB,YAAY;EACZ,UAAU;EACV,WAAW;EACX,sBAAsB;EACtB,sBAAsB;EACtB,yBAAyB;EACzB,kBAAkB;EAClB,eAAe;AACjB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,kBAAkB;AACpB;AACA;EACE,yBAAyB;AAC3B;AACA;EACE,sBAAsB;AACxB;AACA;;EAEE,sBAAsB;EACtB,kBAAkB;EAClB,gBAAgB;EAChB,mBAAmB;AACrB;AACA;;EAEE,8BAA8B;AAChC;AACA;EACE,WAAW;EACX,YAAY;EACZ,cAAc;AAChB;AACA;EACE,UAAU;EACV,YAAY;AACd;AACA;EACE,SAAS;EACT,SAAS;EACT,UAAU;AACZ;AACA;EACE,aAAa;EACb,iBAAiB;EACjB,mBAAmB;AACrB;AACA;EACE,MAAM;EACN,UAAU;EACV,YAAY;AACd;AACA;EACE,UAAU;EACV,YAAY;AACd;AACA;EACE,iBAAiB;AACnB;AACA;;EAEE,yBAAyB;EACzB,wBAAwB;EACxB,yBAAyB;EACzB,4BAA4B;AAC9B;AACA;EACE,yBAAyB;EACzB,wBAAwB;EACxB,yBAAyB;EACzB,4BAA4B;AAC9B;AACA;;EAEE,yCAAyC;EACzC,6BAA6B;AAC/B;AACA;EACE,0CAA0C;EAC1C,6BAA6B;AAC/B;AACA;;EAEE,sBAAsB;EACtB,yDAAyD;AAC3D;AACA;EACE,iEAAiE;AACnE;AACA;EACE;IACE,sBAAsB;IACtB,0BAA0B;IAC1B,UAAU;EACZ;EACA;IACE,sBAAsB;IACtB,0BAA0B;EAC5B;AACF;AACA;EACE;IACE,sBAAsB;IACtB,0BAA0B;EAC5B;EACA;IACE,sBAAsB;IACtB,0BAA0B;IAC1B,UAAU;EACZ;AACF;AACA;EACE,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,aAAa;AACf;AACA;EACE,oBAAoB;AACtB;AACA;EACE,eAAe;EACf,YAAY;EACZ,gBAAgB;EAChB,WAAW;EACX,eAAe;EACf,cAAc;EACd,kBAAkB;EAClB,qBAAqB;EACrB,yBAAyB;EACzB,kBAAkB;EAClB,2BAA2B;AAC7B;AACA;EACE,kBAAkB;EAClB,QAAQ;EACR,SAAS;EACT,yBAAyB;EACzB,mBAAmB;AACrB;AACA;EACE,WAAW;EACX,SAAS;EACT,iBAAiB;EACjB,uBAAuB;EACvB,yBAAyB;AAC3B","sourcesContent":[".rc-slider {\\n position: relative;\\n width: 100%;\\n height: 14px;\\n padding: 5px 0;\\n border-radius: 6px;\\n touch-action: none;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-rail {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background-color: #e9e9e9;\\n border-radius: 6px;\\n}\\n.rc-slider-track {\\n position: absolute;\\n height: 4px;\\n background-color: #abe2fb;\\n border-radius: 6px;\\n}\\n.rc-slider-handle {\\n position: absolute;\\n width: 14px;\\n height: 14px;\\n margin-top: -5px;\\n background-color: #fff;\\n border: solid 2px #96dbfa;\\n border-radius: 50%;\\n cursor: pointer;\\n cursor: -webkit-grab;\\n cursor: grab;\\n opacity: 0.8;\\n touch-action: pan-x;\\n}\\n.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {\\n border-color: #57c5f7;\\n box-shadow: 0 0 0 5px #96dbfa;\\n}\\n.rc-slider-handle:focus {\\n outline: none;\\n box-shadow: none;\\n}\\n.rc-slider-handle:focus-visible {\\n border-color: #2db7f5;\\n box-shadow: 0 0 0 3px #96dbfa;\\n}\\n.rc-slider-handle-click-focused:focus {\\n border-color: #96dbfa;\\n box-shadow: unset;\\n}\\n.rc-slider-handle:hover {\\n border-color: #57c5f7;\\n}\\n.rc-slider-handle:active {\\n border-color: #57c5f7;\\n box-shadow: 0 0 5px #57c5f7;\\n cursor: -webkit-grabbing;\\n cursor: grabbing;\\n}\\n.rc-slider-mark {\\n position: absolute;\\n top: 18px;\\n left: 0;\\n width: 100%;\\n font-size: 12px;\\n}\\n.rc-slider-mark-text {\\n position: absolute;\\n display: inline-block;\\n color: #999;\\n text-align: center;\\n vertical-align: middle;\\n cursor: pointer;\\n}\\n.rc-slider-mark-text-active {\\n color: #666;\\n}\\n.rc-slider-step {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background: transparent;\\n pointer-events: none;\\n}\\n.rc-slider-dot {\\n position: absolute;\\n bottom: -2px;\\n width: 8px;\\n height: 8px;\\n vertical-align: middle;\\n background-color: #fff;\\n border: 2px solid #e9e9e9;\\n border-radius: 50%;\\n cursor: pointer;\\n}\\n.rc-slider-dot-active {\\n border-color: #96dbfa;\\n}\\n.rc-slider-dot-reverse {\\n margin-right: -4px;\\n}\\n.rc-slider-disabled {\\n background-color: #e9e9e9;\\n}\\n.rc-slider-disabled .rc-slider-track {\\n background-color: #ccc;\\n}\\n.rc-slider-disabled .rc-slider-handle,\\n.rc-slider-disabled .rc-slider-dot {\\n background-color: #fff;\\n border-color: #ccc;\\n box-shadow: none;\\n cursor: not-allowed;\\n}\\n.rc-slider-disabled .rc-slider-mark-text,\\n.rc-slider-disabled .rc-slider-dot {\\n cursor: not-allowed !important;\\n}\\n.rc-slider-vertical {\\n width: 14px;\\n height: 100%;\\n padding: 0 5px;\\n}\\n.rc-slider-vertical .rc-slider-rail {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-track {\\n bottom: 0;\\n left: 5px;\\n width: 4px;\\n}\\n.rc-slider-vertical .rc-slider-handle {\\n margin-top: 0;\\n margin-left: -5px;\\n touch-action: pan-y;\\n}\\n.rc-slider-vertical .rc-slider-mark {\\n top: 0;\\n left: 18px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-step {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-dot {\\n margin-left: -2px;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,\\n.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {\\n animation-name: rcSliderTooltipZoomDownIn;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {\\n animation-name: rcSliderTooltipZoomDownOut;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n transform: scale(0, 0);\\n animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);\\n}\\n@keyframes rcSliderTooltipZoomDownIn {\\n 0% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n 100% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n}\\n@keyframes rcSliderTooltipZoomDownOut {\\n 0% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n 100% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n}\\n.rc-slider-tooltip {\\n position: absolute;\\n top: -9999px;\\n left: -9999px;\\n visibility: visible;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip-hidden {\\n display: none;\\n}\\n.rc-slider-tooltip-placement-top {\\n padding: 4px 0 8px 0;\\n}\\n.rc-slider-tooltip-inner {\\n min-width: 24px;\\n height: 24px;\\n padding: 6px 2px;\\n color: #fff;\\n font-size: 12px;\\n line-height: 1;\\n text-align: center;\\n text-decoration: none;\\n background-color: #6c6c6c;\\n border-radius: 6px;\\n box-shadow: 0 0 4px #d9d9d9;\\n}\\n.rc-slider-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {\\n bottom: 4px;\\n left: 50%;\\n margin-left: -4px;\\n border-width: 4px 4px 0;\\n border-top-color: #6c6c6c;\\n}\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFdBQVcsVUFBVSxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxhQUFhLGFBQWEsV0FBVyxZQUFZLFdBQVcsVUFBVSxZQUFZLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxLQUFLLFVBQVUsWUFBWSxNQUFNLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksYUFBYSxhQUFhLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFVBQVUsVUFBVSxNQUFNLEtBQUssWUFBWSxhQUFhLFdBQVcsWUFBWSxhQUFhLFdBQVcsTUFBTSxLQUFLLFVBQVUsS0FBSyxLQUFLLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxNQUFNLEtBQUssWUFBWSxXQUFXLFVBQVUsVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLFdBQVcsTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxNQUFNLFlBQVksYUFBYSxhQUFhLGFBQWEsTUFBTSxNQUFNLFlBQVksTUFBTSxLQUFLLFVBQVUsVUFBVSxVQUFVLE1BQU0sS0FBSyxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxVQUFVLEtBQUssS0FBSyxVQUFVLFlBQVksYUFBYSxNQUFNLEtBQUssVUFBVSxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssWUFBWSxNQUFNLE1BQU0sWUFBWSxhQUFhLGFBQWEsYUFBYSxNQUFNLEtBQUssWUFBWSxhQUFhLGFBQWEsYUFBYSxNQUFNLE1BQU0sWUFBWSxhQUFhLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxNQUFNLFlBQVksYUFBYSxNQUFNLEtBQUssWUFBWSxNQUFNLEtBQUssS0FBSyxZQUFZLGFBQWEsV0FBVyxLQUFLLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxLQUFLLEtBQUssWUFBWSxhQUFh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QUE4Qix3QkFBd0IsR0FBRyw2REFBNkQsZ0JBQWdCLGNBQWMsc0JBQXNCLDRCQUE0Qiw4QkFBOEIsR0FBRyxxQkFBcUI7QUFDLy9hO0FBQ0EsaUVBQWUsdUJBQXVCLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2Fzc2V0cy9pbmRleC5jc3M/YTA3YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgXCIucmMtc2xpZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgaGVpZ2h0OiAxNHB4O1xcbiAgcGFkZGluZzogNXB4IDA7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICB0b3VjaC1hY3Rpb246IG5vbmU7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiByZ2JhKDAsIDAsIDAsIDApO1xcbn1cXG4ucmMtc2xpZGVyICoge1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci1yYWlsIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgaGVpZ2h0OiA0cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZTllOWU5O1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbn1cXG4ucmMtc2xpZGVyLXRyYWNrIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGhlaWdodDogNHB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2FiZTJmYjtcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDE0cHg7XFxuICBoZWlnaHQ6IDE0cHg7XFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcXG4gIGJvcmRlcjogc29saWQgMnB4ICM5NmRiZmE7XFxuICBib3JkZXItcmFkaXVzOiA1MCU7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBjdXJzb3I6IC13ZWJraXQtZ3JhYjtcXG4gIGN1cnNvcjogZ3JhYjtcXG4gIG9wYWNpdHk6IDAuODtcXG4gIHRvdWNoLWFjdGlvbjogcGFuLXg7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlLWRyYWdnaW5nLnJjLXNsaWRlci1oYW5kbGUtZHJhZ2dpbmcucmMtc2xpZGVyLWhhbmRsZS1kcmFnZ2luZyB7XFxuICBib3JkZXItY29sb3I6ICM1N2M1Zjc7XFxuICBib3gtc2hhZG93OiAwIDAgMCA1cHggIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6Zm9jdXMge1xcbiAgb3V0bGluZTogbm9uZTtcXG4gIGJveC1zaGFkb3c6IG5vbmU7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlOmZvY3VzLXZpc2libGUge1xcbiAgYm9yZGVyLWNvbG9yOiAjMmRiN2Y1O1xcbiAgYm94LXNoYWRvdzogMCAwIDAgM3B4ICM5NmRiZmE7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlLWNsaWNrLWZvY3VzZWQ6Zm9jdXMge1xcbiAgYm9yZGVyLWNvbG9yOiAjOTZkYmZhO1xcbiAgYm94LXNoYWRvdzogdW5zZXQ7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlOmhvdmVyIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6YWN0aXZlIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG4gIGJveC1zaGFkb3c6IDAgMCA1cHggIzU3YzVmNztcXG4gIGN1cnNvcjogLXdlYmtpdC1ncmFiYmluZztcXG4gIGN1cnNvcjogZ3JhYmJpbmc7XFxufVxcbi5yYy1zbGlkZXItbWFyayB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDE4cHg7XFxuICBsZWZ0OiAwO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBmb250LXNpemU6IDEycHg7XFxufVxcbi5yYy1zbGlkZXItbWFyay10ZXh0IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXG4gIGNvbG9yOiAjOTk5O1xcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLnJjLXNsaWRlci1tYXJrLXRleHQtYWN0aXZlIHtcXG4gIGNvbG9yOiAjNjY2O1xcbn1cXG4ucmMtc2xpZGVyLXN0ZXAge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDRweDtcXG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcbi5yYy1zbGlkZXItZG90IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGJvdHRvbTogLTJweDtcXG4gIHdpZHRoOiA4cHg7XFxuICBoZWlnaHQ6IDhweDtcXG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyOiAycHggc29saWQgI2U5ZTllOTtcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLnJjLXNsaWRlci1kb3QtYWN0aXZlIHtcXG4gIGJvcmRlci1jb2xvcjogIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1kb3QtcmV2ZXJzZSB7XFxuICBtYXJnaW4tcmlnaHQ6IC00cHg7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2U5ZTllOTtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLXRyYWNrIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNjY2M7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQgLnJjLXNsaWRlci1oYW5kbGUsXFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWRvdCB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyLWNvbG9yOiAjY2NjO1xcbiAgYm94LXNoYWRvdzogbm9uZTtcXG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQgLnJjLXNsaWRlci1tYXJrLXRleHQsXFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWRvdCB7XFxuICBjdXJzb3I6IG5vdC1hbGxvd2VkICFpbXBvcnRhbnQ7XFxufVxcbi5yYy1zbGlkZXItdmVydGljYWwge1xcbiAgd2lkdGg6IDE0cHg7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBwYWRkaW5nOiAwIDVweDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXJhaWwge1xcbiAgd2lkdGg6IDRweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXRyYWNrIHtcXG4gIGJvdHRvbTogMDtcXG4gIGxlZnQ6IDVweDtcXG4gIHdpZHRoOiA0cHg7XFxufVxcbi5yYy1zbGlkZXItdmVydGljYWwgLnJjLXNsaWRlci1oYW5kbGUge1xcbiAgbWFyZ2luLXRvcDogMDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgdG91Y2gtYWN0aW9uOiBwYW4teTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLW1hcmsge1xcbiAgdG9wOiAwO1xcbiAgbGVmdDogMThweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXN0ZXAge1xcbiAgd2lkdGg6IDRweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLWRvdCB7XFxuICBtYXJnaW4tbGVmdDogLTJweDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1lbnRlcixcXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhciB7XFxuICBkaXNwbGF5OiBibG9jayAhaW1wb3J0YW50O1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAwLjNzO1xcbiAgYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUge1xcbiAgZGlzcGxheTogYmxvY2sgIWltcG9ydGFudDtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1lbnRlci1hY3RpdmUsXFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1hcHBlYXIucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhci1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duSW47XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcnVubmluZztcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZS5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUtYWN0aXZlIHtcXG4gIGFuaW1hdGlvbi1uYW1lOiByY1NsaWRlclRvb2x0aXBab29tRG93bk91dDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLFxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyIHtcXG4gIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUge1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuNzU1LCAwLjA1LCAwLjg1NSwgMC4wNik7XFxufVxcbkBrZXlmcmFtZXMgcmNTbGlkZXJUb29sdGlwWm9vbURvd25JbiB7XFxuICAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSAxMDAlO1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgfVxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSAxMDAlO1xcbiAgfVxcbn1cXG5Aa2V5ZnJhbWVzIHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duT3V0IHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICAgIG9wYWNpdHk6IDA7XFxuICB9XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IC05OTk5cHg7XFxuICBsZWZ0OiAtOTk5OXB4O1xcbiAgdmlzaWJpbGl0eTogdmlzaWJsZTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcCAqIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1oaWRkZW4ge1xcbiAgZGlzcGxheTogbm9uZTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXBsYWNlbWVudC10b3Age1xcbiAgcGFkZGluZzogNHB4IDAgOHB4IDA7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1pbm5lciB7XFxuICBtaW4td2lkdGg6IDI0cHg7XFxuICBoZWlnaHQ6IDI0cHg7XFxuICBwYWRkaW5nOiA2cHggMnB4O1xcbiAgY29sb3I6ICNmZmY7XFxuICBmb250LXNpemU6IDEycHg7XFxuICBsaW5lLWhlaWdodDogMTtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICM2YzZjNmM7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICBib3gtc2hhZG93OiAwIDAgNHB4ICNkOWQ5ZDk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1hcnJvdyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMDtcXG4gIGhlaWdodDogMDtcXG4gIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XFxuICBib3JkZXItc3R5bGU6IHNvbGlkO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtc2xpZGVyLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiA0cHg7XFxuICBsZWZ0OiA1MCU7XFxuICBtYXJnaW4tbGVmdDogLTRweDtcXG4gIGJvcmRlci13aWR0aDogNHB4IDRweCAwO1xcbiAgYm9yZGVyLXRvcC1jb2xvcjogIzZjNmM2YztcXG59XFxuXCIsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9hc3NldHMvaW5kZXguY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxZQUFZO0VBQ1osY0FBYztFQUNkLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsc0JBQXNCO0VBQ3RCLDZDQUE2QztBQUMvQztBQUNBO0VBQ0Usc0JBQXNCO0VBQ3RCLDZDQUE2QztBQUMvQztBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxXQUFXO0VBQ1gseUJBQXlCO0VBQ3pCLGtCQUFrQjtBQUNwQjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCx5QkFBeUI7RUFDekIsa0JBQWtCO0FBQ3BCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIsV0FBVztFQUNYLFlBQVk7RUFDWixnQkFBZ0I7RUFDaEIsc0JBQXNCO0VBQ3RCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsZUFBZTtFQUNmLG9CQUFvQjtFQUNwQixZQUFZO0VBQ1osWUFBWTtFQUNaLG1CQUFtQjtBQUNyQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLDZCQUE2QjtBQUMvQjtBQUNBO0VBQ0UsYUFBYTtFQUNiLGdCQUFnQjtBQUNsQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLDZCQUE2QjtBQUMvQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLGlCQUFpQjtBQUNuQjtBQUNBO0VBQ0UscUJBQXFCO0FBQ3ZCO0FBQ0E7RUFDRSxxQkFBcUI7RUFDckIsMkJBQTJCO0VBQzNCLHdCQUF3QjtFQUN4QixnQkFBZ0I7QUFDbEI7QUFDQTtFQUNFLGtCQUFrQjtFQUNsQixTQUFTO0VBQ1QsT0FBTztFQUNQLFdBQVc7RUFDWCxlQUFlO0FBQ2pCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIscUJBQXFCO0VBQ3JCLFdBQVc7RUFDWCxrQkFBa0I7RUFDbEIsc0JBQXNCO0VBQ3RCLGVBQWU7QUFDakI7QUFDQTtFQUNFLFdBQVc7QUFDYjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxXQUFXO0VBQ1gsdUJBQXVCO0VBQ3ZCLG9CQUFvQjtBQUN0QjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFlBQVk7RUFDWixVQUFVO0VBQ1YsV0FBVztFQUNYLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIseUJBQXlCO0VBQ3pCLGtCQUFrQjtFQUNsQixlQUFlO0FBQ2pCO0FBQ0E7RUFDRSxxQkFBcUI7QUFDdkI7QUFDQTtFQUNFLGtCQUFrQjtBQUNwQjtBQUNBO0VBQ0UseUJBQXlCO0FBQzNCO0FBQ0E7RUFDRSxzQkFBc0I7QUFDeEI7QUFDQTs7RUFFRSxzQkFBc0I7RUFDdEIsa0JBQWtCO0VBQ2xCLGdCQUFnQjtFQUNoQixtQkFBbUI7QUFDckI7QUFDQTs7RUFFRSw4QkFBOEI7QUFDaEM7QUFDQTtFQUNFLFdBQVc7RUFDWCxZQUFZO0VBQ1osY0FBYztBQUNoQjtBQUNBO0VBQ0UsVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsU0FBUztFQUNULFNBQVM7RUFDVCxVQUFVO0FBQ1o7QUFDQTtFQUNFLGFBQWE7RUFDYixpQkFBaUI7RUFDakIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxNQUFNO0VBQ04sVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsaUJBQWlCO0FBQ25CO0FBQ0E7O0VBRUUseUJBQXlCO0VBQ3pCLHdCQUF3QjtFQUN4Qix5QkFBeUI7RUFDekIsNEJBQTRCO0FBQzlCO0FBQ0E7RUFDRSx5QkFBeUI7RUFDekIsd0JBQXdCO0VBQ3hCLHlCQUF5QjtFQUN6Qiw0QkFBNEI7QUFDOUI7QUFDQTs7RUFFRSx5Q0FBeUM7RUFDekMsNkJBQTZCO0FBQy9CO0FBQ0E7RUFDRSwwQ0FBMEM7RUFDMUMsNkJBQTZCO0FBQy9CO0FBQ0E7O0VBRUUsc0JBQXNCO0VBQ3RCLHlEQUF5RDtBQUMzRDtBQUNBO0VBQ0UsaUVBQWlFO0FBQ25FO0FBQ0E7RUFDRTtJQUNFLHNCQUFzQjtJQUN0QiwwQkFBMEI7SUFDMUIsVUFBVTtFQUNaO0VBQ0E7SUFDRSxzQkFBc0I7SUFDdEIsMEJBQTBCO0VBQzVCO0FBQ0Y7QUFDQTtFQUNFO0lBQ0Usc0JBQXNCO0lBQ3RCLDBCQUEwQjtFQUM1QjtFQUNBO0lBQ0Usc0JBQXNCO0lBQ3RCLDBCQUEwQjtJQUMxQixVQUFVO0VBQ1o7QUFDRjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFlBQVk7RUFDWixhQUFhO0VBQ2IsbUJBQW1CO0VBQ25CLHNCQUFzQjtFQUN0Qiw2Q0FBNkM7QUFDL0M7QUFDQTtFQUNFLHNCQUFzQjtFQUN0Qiw2Q0FBNkM7QUFDL0M7QUFDQTtFQUNFLGFBQWE7QUFDZjtBQUNBO0VBQ0Usb0JBQW9CO0FBQ3RCO0FBQ0E7RUFDRSxlQUFlO0VBQ2YsWUFBWTtFQUNaLGdCQUFnQjtFQUNoQixXQUFXO0VBQ1gsZUFBZTtFQUNmLGNBQWM7RUFDZCxrQkFBa0I7RUFDbEIscUJBQXFCO0VBQ3JCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsMkJBQTJCO0FBQzdCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIsUUFBUTtFQUNSLFNBQVM7RUFDVCx5QkFBeUI7RUFDekIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxXQUFXO0VBQ1gsU0FBUztFQUNULGlCQUFpQjtFQUNqQix1QkFBdUI7RUFDdkIseUJBQXlCO0FBQzNCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5yYy1zbGlkZXIge1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDE0cHg7XFxuICBwYWRkaW5nOiA1cHggMDtcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG4gIHRvdWNoLWFjdGlvbjogbm9uZTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXIgKiB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiByZ2JhKDAsIDAsIDAsIDApO1xcbn1cXG4ucmMtc2xpZGVyLXJhaWwge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDRweDtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNlOWU5ZTk7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxufVxcbi5yYy1zbGlkZXItdHJhY2sge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgaGVpZ2h0OiA0cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjYWJlMmZiO1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZSB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMTRweDtcXG4gIGhlaWdodDogMTRweDtcXG4gIG1hcmdpbi10b3A6IC01cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyOiBzb2xpZCAycHggIzk2ZGJmYTtcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG4gIGN1cnNvcjogLXdlYmtpdC1ncmFiO1xcbiAgY3Vyc29yOiBncmFiO1xcbiAgb3BhY2l0eTogMC44O1xcbiAgdG91Y2gtYWN0aW9uOiBwYW4teDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUtZHJhZ2dpbmcucmMtc2xpZGVyLWhhbmRsZS1kcmFnZ2luZy5yYy1zbGlkZXItaGFuZGxlLWRyYWdnaW5nIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG4gIGJveC1zaGFkb3c6IDAgMCAwIDVweCAjOTZkYmZhO1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZTpmb2N1cyB7XFxuICBvdXRsaW5lOiBub25lO1xcbiAgYm94LXNoYWRvdzogbm9uZTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6Zm9jdXMtdmlzaWJsZSB7XFxuICBib3JkZXItY29sb3I6ICMyZGI3ZjU7XFxuICBib3gtc2hhZG93OiAwIDAgMCAzcHggIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUtY2xpY2stZm9jdXNlZDpmb2N1cyB7XFxuICBib3JkZXItY29sb3I6ICM5NmRiZmE7XFxuICBib3gtc2hhZG93OiB1bnNldDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6aG92ZXIge1xcbiAgYm9yZGVyLWNvbG9yOiAjNTdjNWY3O1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZTphY3RpdmUge1xcbiAgYm9yZGVyLWNvbG9yOiAjNTdjNWY3O1xcbiAgYm94LXNoYWRvdzogMCAwIDVweCAjNTdjNWY3O1xcbiAgY3Vyc29yOiAtd2Via2l0LWdyYWJiaW5nO1xcbiAgY3Vyc29yOiBncmFiYmluZztcXG59XFxuLnJjLXNsaWRlci1tYXJrIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMThweDtcXG4gIGxlZnQ6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG59XFxuLnJjLXNsaWRlci1tYXJrLXRleHQge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgY29sb3I6ICM5OTk7XFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ucmMtc2xpZGVyLW1hcmstdGV4dC1hY3RpdmUge1xcbiAgY29sb3I6ICM2NjY7XFxufVxcbi5yYy1zbGlkZXItc3RlcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogNHB4O1xcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXG59XFxuLnJjLXNsaWRlci1kb3Qge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgYm90dG9tOiAtMnB4O1xcbiAgd2lkdGg6IDhweDtcXG4gIGhlaWdodDogOHB4O1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXI6IDJweCBzb2xpZCAjZTllOWU5O1xcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ucmMtc2xpZGVyLWRvdC1hY3RpdmUge1xcbiAgYm9yZGVyLWNvbG9yOiAjOTZkYmZhO1xcbn1cXG4ucmMtc2xpZGVyLWRvdC1yZXZlcnNlIHtcXG4gIG1hcmdpbi1yaWdodDogLTRweDtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZTllOWU5O1xcbn1cXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItdHJhY2sge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2NjYztcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWhhbmRsZSxcXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItZG90IHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXItY29sb3I6ICNjY2M7XFxuICBib3gtc2hhZG93OiBub25lO1xcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLW1hcmstdGV4dCxcXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItZG90IHtcXG4gIGN1cnNvcjogbm90LWFsbG93ZWQgIWltcG9ydGFudDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCB7XFxuICB3aWR0aDogMTRweDtcXG4gIGhlaWdodDogMTAwJTtcXG4gIHBhZGRpbmc6IDAgNXB4O1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItcmFpbCB7XFxuICB3aWR0aDogNHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItdHJhY2sge1xcbiAgYm90dG9tOiAwO1xcbiAgbGVmdDogNXB4O1xcbiAgd2lkdGg6IDRweDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLWhhbmRsZSB7XFxuICBtYXJnaW4tdG9wOiAwO1xcbiAgbWFyZ2luLWxlZnQ6IC01cHg7XFxuICB0b3VjaC1hY3Rpb246IHBhbi15O1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItbWFyayB7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAxOHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItc3RlcCB7XFxuICB3aWR0aDogNHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItZG90IHtcXG4gIG1hcmdpbi1sZWZ0OiAtMnB4O1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLFxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyIHtcXG4gIGRpc3BsYXk6IGJsb2NrICFpbXBvcnRhbnQ7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHBhdXNlZDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZSB7XFxuICBkaXNwbGF5OiBibG9jayAhaW1wb3J0YW50O1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAwLjNzO1xcbiAgYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tZW50ZXIucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLWFjdGl2ZSxcXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhci5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNTbGlkZXJUb29sdGlwWm9vbURvd25JbjtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWxlYXZlLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZS1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duT3V0O1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHJ1bm5pbmc7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tZW50ZXIsXFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1hcHBlYXIge1xcbiAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gIGFuaW1hdGlvbi10aW1pbmctZnVuY3Rpb246IGN1YmljLWJlemllcigwLjIzLCAxLCAwLjMyLCAxKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZSB7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC43NTUsIDAuMDUsIDAuODU1LCAwLjA2KTtcXG59XFxuQGtleWZyYW1lcyByY1NsaWRlclRvb2x0aXBab29tRG93bkluIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICAgIG9wYWNpdHk6IDA7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICB9XFxufVxcbkBrZXlmcmFtZXMgcmNTbGlkZXJUb29sdGlwWm9vbURvd25PdXQge1xcbiAgMCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEsIDEpO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgMTAwJTtcXG4gIH1cXG4gIDEwMCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgMTAwJTtcXG4gICAgb3BhY2l0eTogMDtcXG4gIH1cXG59XFxuLnJjLXNsaWRlci10b29sdGlwIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogLTk5OTlweDtcXG4gIGxlZnQ6IC05OTk5cHg7XFxuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwICoge1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWhpZGRlbiB7XFxuICBkaXNwbGF5OiBub25lO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtcGxhY2VtZW50LXRvcCB7XFxuICBwYWRkaW5nOiA0cHggMCA4cHggMDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWlubmVyIHtcXG4gIG1pbi13aWR0aDogMjRweDtcXG4gIGhlaWdodDogMjRweDtcXG4gIHBhZGRpbmc6IDZweCAycHg7XFxuICBjb2xvcjogI2ZmZjtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG4gIGxpbmUtaGVpZ2h0OiAxO1xcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogIzZjNmM2YztcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG4gIGJveC1zaGFkb3c6IDAgMCA0cHggI2Q5ZDlkOTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWFycm93IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHdpZHRoOiAwO1xcbiAgaGVpZ2h0OiAwO1xcbiAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcXG4gIGJvcmRlci1zdHlsZTogc29saWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy1zbGlkZXItdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDRweDtcXG4gIGxlZnQ6IDUwJTtcXG4gIG1hcmdpbi1sZWZ0OiAtNHB4O1xcbiAgYm9yZGVyLXdpZHRoOiA0cHggNHB4IDA7XFxuICBib3JkZXItdG9wLWNvbG9yOiAjNmM2YzZjO1xcbn1cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///687\n')},467:(module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(537);\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(645);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ".rc-tooltip.rc-tooltip-zoom-appear,\\n.rc-tooltip.rc-tooltip-zoom-enter {\\n opacity: 0;\\n}\\n.rc-tooltip.rc-tooltip-zoom-enter,\\n.rc-tooltip.rc-tooltip-zoom-leave {\\n display: block;\\n}\\n.rc-tooltip-zoom-enter,\\n.rc-tooltip-zoom-appear {\\n opacity: 0;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-leave {\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,\\n.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {\\n animation-name: rcToolTipZoomIn;\\n animation-play-state: running;\\n}\\n.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {\\n animation-name: rcToolTipZoomOut;\\n animation-play-state: running;\\n}\\n@keyframes rcToolTipZoomIn {\\n 0% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n 100% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n}\\n@keyframes rcToolTipZoomOut {\\n 0% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n 100% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n}\\n.rc-tooltip {\\n position: absolute;\\n z-index: 1070;\\n display: block;\\n visibility: visible;\\n font-size: 12px;\\n line-height: 1.5;\\n opacity: 0.9;\\n}\\n.rc-tooltip-hidden {\\n display: none;\\n}\\n.rc-tooltip-placement-top,\\n.rc-tooltip-placement-topLeft,\\n.rc-tooltip-placement-topRight {\\n padding: 5px 0 9px 0;\\n}\\n.rc-tooltip-placement-right,\\n.rc-tooltip-placement-rightTop,\\n.rc-tooltip-placement-rightBottom {\\n padding: 0 5px 0 9px;\\n}\\n.rc-tooltip-placement-bottom,\\n.rc-tooltip-placement-bottomLeft,\\n.rc-tooltip-placement-bottomRight {\\n padding: 9px 0 5px 0;\\n}\\n.rc-tooltip-placement-left,\\n.rc-tooltip-placement-leftTop,\\n.rc-tooltip-placement-leftBottom {\\n padding: 0 9px 0 5px;\\n}\\n.rc-tooltip-inner {\\n padding: 8px 10px;\\n color: #fff;\\n text-align: left;\\n text-decoration: none;\\n background-color: #373737;\\n border-radius: 6px;\\n box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);\\n min-height: 34px;\\n}\\n.rc-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow,\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n bottom: 4px;\\n margin-left: -5px;\\n border-width: 5px 5px 0;\\n border-top-color: #373737;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n left: 4px;\\n margin-top: -5px;\\n border-width: 5px 5px 5px 0;\\n border-right-color: #373737;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n right: 4px;\\n margin-top: -5px;\\n border-width: 5px 0 5px 5px;\\n border-left-color: #373737;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n top: 4px;\\n margin-left: -5px;\\n border-width: 0 5px 5px;\\n border-bottom-color: #373737;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n", "",{"version":3,"sources":["webpack://./node_modules/rc-tooltip/assets/bootstrap.css"],"names":[],"mappings":"AAAA;;EAEE,UAAU;AACZ;AACA;;EAEE,cAAc;AAChB;AACA;;EAEE,UAAU;EACV,wBAAwB;EACxB,yBAAyB;EACzB,+DAA+D;EAC/D,4BAA4B;AAC9B;AACA;EACE,wBAAwB;EACxB,yBAAyB;EACzB,8DAA8D;EAC9D,4BAA4B;AAC9B;AACA;;EAEE,+BAA+B;EAC/B,6BAA6B;AAC/B;AACA;EACE,gCAAgC;EAChC,6BAA6B;AAC/B;AACA;EACE;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;EACA;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;AACF;AACA;EACE;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;EACA;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;AACF;AACA;EACE,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,mBAAmB;EACnB,eAAe;EACf,gBAAgB;EAChB,YAAY;AACd;AACA;EACE,aAAa;AACf;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;EACE,iBAAiB;EACjB,WAAW;EACX,gBAAgB;EAChB,qBAAqB;EACrB,yBAAyB;EACzB,kBAAkB;EAClB,uCAAuC;EACvC,gBAAgB;AAClB;AACA;EACE,kBAAkB;EAClB,QAAQ;EACR,SAAS;EACT,yBAAyB;EACzB,mBAAmB;AACrB;AACA;;;EAGE,WAAW;EACX,iBAAiB;EACjB,uBAAuB;EACvB,yBAAyB;AAC3B;AACA;EACE,SAAS;AACX;AACA;EACE,SAAS;AACX;AACA;EACE,UAAU;AACZ;AACA;;;EAGE,SAAS;EACT,gBAAgB;EAChB,2BAA2B;EAC3B,2BAA2B;AAC7B;AACA;EACE,QAAQ;AACV;AACA;EACE,QAAQ;EACR,aAAa;AACf;AACA;EACE,WAAW;AACb;AACA;;;EAGE,UAAU;EACV,gBAAgB;EAChB,2BAA2B;EAC3B,0BAA0B;AAC5B;AACA;EACE,QAAQ;AACV;AACA;EACE,QAAQ;EACR,aAAa;AACf;AACA;EACE,WAAW;AACb;AACA;;;EAGE,QAAQ;EACR,iBAAiB;EACjB,uBAAuB;EACvB,4BAA4B;AAC9B;AACA;EACE,SAAS;AACX;AACA;EACE,SAAS;AACX;AACA;EACE,UAAU;AACZ","sourcesContent":[".rc-tooltip.rc-tooltip-zoom-appear,\\n.rc-tooltip.rc-tooltip-zoom-enter {\\n opacity: 0;\\n}\\n.rc-tooltip.rc-tooltip-zoom-enter,\\n.rc-tooltip.rc-tooltip-zoom-leave {\\n display: block;\\n}\\n.rc-tooltip-zoom-enter,\\n.rc-tooltip-zoom-appear {\\n opacity: 0;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-leave {\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,\\n.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {\\n animation-name: rcToolTipZoomIn;\\n animation-play-state: running;\\n}\\n.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {\\n animation-name: rcToolTipZoomOut;\\n animation-play-state: running;\\n}\\n@keyframes rcToolTipZoomIn {\\n 0% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n 100% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n}\\n@keyframes rcToolTipZoomOut {\\n 0% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n 100% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n}\\n.rc-tooltip {\\n position: absolute;\\n z-index: 1070;\\n display: block;\\n visibility: visible;\\n font-size: 12px;\\n line-height: 1.5;\\n opacity: 0.9;\\n}\\n.rc-tooltip-hidden {\\n display: none;\\n}\\n.rc-tooltip-placement-top,\\n.rc-tooltip-placement-topLeft,\\n.rc-tooltip-placement-topRight {\\n padding: 5px 0 9px 0;\\n}\\n.rc-tooltip-placement-right,\\n.rc-tooltip-placement-rightTop,\\n.rc-tooltip-placement-rightBottom {\\n padding: 0 5px 0 9px;\\n}\\n.rc-tooltip-placement-bottom,\\n.rc-tooltip-placement-bottomLeft,\\n.rc-tooltip-placement-bottomRight {\\n padding: 9px 0 5px 0;\\n}\\n.rc-tooltip-placement-left,\\n.rc-tooltip-placement-leftTop,\\n.rc-tooltip-placement-leftBottom {\\n padding: 0 9px 0 5px;\\n}\\n.rc-tooltip-inner {\\n padding: 8px 10px;\\n color: #fff;\\n text-align: left;\\n text-decoration: none;\\n background-color: #373737;\\n border-radius: 6px;\\n box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);\\n min-height: 34px;\\n}\\n.rc-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow,\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n bottom: 4px;\\n margin-left: -5px;\\n border-width: 5px 5px 0;\\n border-top-color: #373737;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n left: 4px;\\n margin-top: -5px;\\n border-width: 5px 5px 5px 0;\\n border-right-color: #373737;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n right: 4px;\\n margin-top: -5px;\\n border-width: 5px 0 5px 5px;\\n border-left-color: #373737;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n top: 4px;\\n margin-left: -5px;\\n border-width: 0 5px 5px;\\n border-bottom-color: #373737;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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c0QsZ0JBQWdCLEdBQUcsNkpBQTZKLGFBQWEsc0JBQXNCLDRCQUE0QixpQ0FBaUMsR0FBRyxrREFBa0QsY0FBYyxHQUFHLHNEQUFzRCxjQUFjLEdBQUcsdURBQXVELGVBQWUsR0FBRyxxQkFBcUI7QUFDeDRUO0FBQ0EsaUVBQWUsdUJBQXVCLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9hc3NldHMvYm9vdHN0cmFwLmNzcz81OTY0Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBcIi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIsXFxuLnJjLXRvb2x0aXAucmMtdG9vbHRpcC16b29tLWVudGVyIHtcXG4gIG9wYWNpdHk6IDA7XFxufVxcbi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1lbnRlcixcXG4ucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tbGVhdmUge1xcbiAgZGlzcGxheTogYmxvY2s7XFxufVxcbi5yYy10b29sdGlwLXpvb20tZW50ZXIsXFxuLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIge1xcbiAgb3BhY2l0eTogMDtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC4xOCwgMC44OSwgMC4zMiwgMS4yOCk7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWxlYXZlIHtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC42LCAtMC4zLCAwLjc0LCAwLjA1KTtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy10b29sdGlwLXpvb20tZW50ZXIucmMtdG9vbHRpcC16b29tLWVudGVyLWFjdGl2ZSxcXG4ucmMtdG9vbHRpcC16b29tLWFwcGVhci5yYy10b29sdGlwLXpvb20tYXBwZWFyLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNUb29sVGlwWm9vbUluO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHJ1bm5pbmc7XFxufVxcbi5yYy10b29sdGlwLXpvb20tbGVhdmUucmMtdG9vbHRpcC16b29tLWxlYXZlLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNUb29sVGlwWm9vbU91dDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG5Aa2V5ZnJhbWVzIHJjVG9vbFRpcFpvb21JbiB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDA7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gIH1cXG59XFxuQGtleWZyYW1lcyByY1Rvb2xUaXBab29tT3V0IHtcXG4gIDAlIHtcXG4gICAgb3BhY2l0eTogMTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gIH1cXG4gIDEwMCUge1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlO1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgfVxcbn1cXG4ucmMtdG9vbHRpcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB6LWluZGV4OiAxMDcwO1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xcbiAgZm9udC1zaXplOiAxMnB4O1xcbiAgbGluZS1oZWlnaHQ6IDEuNTtcXG4gIG9wYWNpdHk6IDAuOTtcXG59XFxuLnJjLXRvb2x0aXAtaGlkZGVuIHtcXG4gIGRpc3BsYXk6IG5vbmU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3AsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcExlZnQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcFJpZ2h0IHtcXG4gIHBhZGRpbmc6IDVweCAwIDlweCAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0VG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodEJvdHRvbSB7XFxuICBwYWRkaW5nOiAwIDVweCAwIDlweDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tTGVmdCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQge1xcbiAgcGFkZGluZzogOXB4IDAgNXB4IDA7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0VG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIHtcXG4gIHBhZGRpbmc6IDAgOXB4IDAgNXB4O1xcbn1cXG4ucmMtdG9vbHRpcC1pbm5lciB7XFxuICBwYWRkaW5nOiA4cHggMTBweDtcXG4gIGNvbG9yOiAjZmZmO1xcbiAgdGV4dC1hbGlnbjogbGVmdDtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMzNzM3Mzc7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICBib3gtc2hhZG93OiAwIDAgNHB4IHJnYmEoMCwgMCwgMCwgMC4xNyk7XFxuICBtaW4taGVpZ2h0OiAzNHB4O1xcbn1cXG4ucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMDtcXG4gIGhlaWdodDogMDtcXG4gIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XFxuICBib3JkZXItc3R5bGU6IHNvbGlkO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BSaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDRweDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiA1cHggNXB4IDA7XFxuICBib3JkZXItdG9wLWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcExlZnQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcmlnaHQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodFRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20gLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogNHB4O1xcbiAgbWFyZ2luLXRvcDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDVweCA1cHggMDtcXG4gIGJvcmRlci1yaWdodC1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogNTAlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRUb3AgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiAxNSU7XFxuICBtYXJnaW4tdG9wOiAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20gLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiAxNSU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0VG9wIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiA0cHg7XFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiA1cHggMCA1cHggNXB4O1xcbiAgYm9yZGVyLWxlZnQtY29sb3I6ICMzNzM3Mzc7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogNTAlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDE1JTtcXG4gIG1hcmdpbi10b3A6IDA7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGJvdHRvbTogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21MZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21SaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDRweDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiAwIDVweCA1cHg7XFxuICBib3JkZXItYm90dG9tLWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbUxlZnQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcmlnaHQ6IDE1JTtcXG59XFxuXCIsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvYXNzZXRzL2Jvb3RzdHJhcC5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7O0VBRUUsVUFBVTtBQUNaO0FBQ0E7O0VBRUUsY0FBYztBQUNoQjtBQUNBOztFQUVFLFVBQVU7RUFDVix3QkFBd0I7RUFDeEIseUJBQXlCO0VBQ3pCLCtEQUErRDtFQUMvRCw0QkFBNEI7QUFDOUI7QUFDQTtFQUNFLHdCQUF3QjtFQUN4Qix5QkFBeUI7RUFDekIsOERBQThEO0VBQzlELDRCQUE0QjtBQUM5QjtBQUNBOztFQUVFLCtCQUErQjtFQUMvQiw2QkFBNkI7QUFDL0I7QUFDQTtFQUNFLGdDQUFnQztFQUNoQyw2QkFBNkI7QUFDL0I7QUFDQTtFQUNFO0lBQ0UsVUFBVTtJQUNWLHlCQUF5QjtJQUN6QixzQkFBc0I7RUFDeEI7RUFDQTtJQUNFLFVBQVU7SUFDVix5QkFBeUI7SUFDekIsc0JBQXNCO0VBQ3hCO0FBQ0Y7QUFDQTtFQUNFO0lBQ0UsVUFBVTtJQUNWLHlCQUF5QjtJQUN6QixzQkFBc0I7RUFDeEI7RUFDQTtJQUNFLFVBQVU7SUFDVix5QkFBeUI7SUFDekIsc0JBQXNCO0VBQ3hCO0FBQ0Y7QUFDQTtFQUNFLGtCQUFrQjtFQUNsQixhQUFhO0VBQ2IsY0FBYztFQUNkLG1CQUFtQjtFQUNuQixlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLFlBQVk7QUFDZDtBQUNBO0VBQ0UsYUFBYTtBQUNmO0FBQ0E7OztFQUdFLG9CQUFvQjtBQUN0QjtBQUNBOzs7RUFHRSxvQkFBb0I7QUFDdEI7QUFDQTs7O0VBR0Usb0JBQW9CO0FBQ3RCO0FBQ0E7OztFQUdFLG9CQUFvQjtBQUN0QjtBQUNBO0VBQ0UsaUJBQWlCO0VBQ2pCLFdBQVc7RUFDWCxnQkFBZ0I7RUFDaEIscUJBQXFCO0VBQ3JCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsdUNBQXVDO0VBQ3ZDLGdCQUFnQjtBQUNsQjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFFBQVE7RUFDUixTQUFTO0VBQ1QseUJBQXlCO0VBQ3pCLG1CQUFtQjtBQUNyQjtBQUNBOzs7RUFHRSxXQUFXO0VBQ1gsaUJBQWlCO0VBQ2pCLHVCQUF1QjtFQUN2Qix5QkFBeUI7QUFDM0I7QUFDQTtFQUNFLFNBQVM7QUFDWDtBQUNBO0VBQ0UsU0FBUztBQUNYO0FBQ0E7RUFDRSxVQUFVO0FBQ1o7QUFDQTs7O0VBR0UsU0FBUztFQUNULGdCQUFnQjtFQUNoQiwyQkFBMkI7RUFDM0IsMkJBQTJCO0FBQzdCO0FBQ0E7RUFDRSxRQUFRO0FBQ1Y7QUFDQTtFQUNFLFFBQVE7RUFDUixhQUFhO0FBQ2Y7QUFDQTtFQUNFLFdBQVc7QUFDYjtBQUNBOzs7RUFHRSxVQUFVO0VBQ1YsZ0JBQWdCO0VBQ2hCLDJCQUEyQjtFQUMzQiwwQkFBMEI7QUFDNUI7QUFDQTtFQUNFLFFBQVE7QUFDVjtBQUNBO0VBQ0UsUUFBUTtFQUNSLGFBQWE7QUFDZjtBQUNBO0VBQ0UsV0FBVztBQUNiO0FBQ0E7OztFQUdFLFFBQVE7RUFDUixpQkFBaUI7RUFDakIsdUJBQXVCO0VBQ3ZCLDRCQUE0QjtBQUM5QjtBQUNBO0VBQ0UsU0FBUztBQUNYO0FBQ0E7RUFDRSxTQUFTO0FBQ1g7QUFDQTtFQUNFLFVBQVU7QUFDWlwiLFwic291cmNlc0NvbnRlbnRcIjpbXCIucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tYXBwZWFyLFxcbi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1lbnRlciB7XFxuICBvcGFjaXR5OiAwO1xcbn1cXG4ucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tZW50ZXIsXFxuLnJjLXRvb2x0aXAucmMtdG9vbHRpcC16b29tLWxlYXZlIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWVudGVyLFxcbi5yYy10b29sdGlwLXpvb20tYXBwZWFyIHtcXG4gIG9wYWNpdHk6IDA7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuMTgsIDAuODksIDAuMzIsIDEuMjgpO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHBhdXNlZDtcXG59XFxuLnJjLXRvb2x0aXAtem9vbS1sZWF2ZSB7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuNiwgLTAuMywgMC43NCwgMC4wNSk7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWVudGVyLnJjLXRvb2x0aXAtem9vbS1lbnRlci1hY3RpdmUsXFxuLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIucmMtdG9vbHRpcC16b29tLWFwcGVhci1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjVG9vbFRpcFpvb21JbjtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWxlYXZlLnJjLXRvb2x0aXAtem9vbS1sZWF2ZS1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjVG9vbFRpcFpvb21PdXQ7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcnVubmluZztcXG59XFxuQGtleWZyYW1lcyByY1Rvb2xUaXBab29tSW4ge1xcbiAgMCUge1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlO1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgfVxcbiAgMTAwJSB7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICB9XFxufVxcbkBrZXlmcmFtZXMgcmNUb29sVGlwWm9vbU91dCB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMDtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gIH1cXG59XFxuLnJjLXRvb2x0aXAge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgei1pbmRleDogMTA3MDtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgdmlzaWJpbGl0eTogdmlzaWJsZTtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG4gIGxpbmUtaGVpZ2h0OiAxLjU7XFxuICBvcGFjaXR5OiAwLjk7XFxufVxcbi5yYy10b29sdGlwLWhpZGRlbiB7XFxuICBkaXNwbGF5OiBub25lO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BSaWdodCB7XFxuICBwYWRkaW5nOiA1cHggMCA5cHggMDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodFRvcCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20ge1xcbiAgcGFkZGluZzogMCA1cHggMCA5cHg7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b20sXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbUxlZnQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbVJpZ2h0IHtcXG4gIHBhZGRpbmc6IDlweCAwIDVweCAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSB7XFxuICBwYWRkaW5nOiAwIDlweCAwIDVweDtcXG59XFxuLnJjLXRvb2x0aXAtaW5uZXIge1xcbiAgcGFkZGluZzogOHB4IDEwcHg7XFxuICBjb2xvcjogI2ZmZjtcXG4gIHRleHQtYWxpZ246IGxlZnQ7XFxuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzczNzM3O1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbiAgYm94LXNoYWRvdzogMCAwIDRweCByZ2JhKDAsIDAsIDAsIDAuMTcpO1xcbiAgbWluLWhlaWdodDogMzRweDtcXG59XFxuLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDA7XFxuICBoZWlnaHQ6IDA7XFxuICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xcbiAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wTGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiA0cHg7XFxuICBtYXJnaW4tbGVmdDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDVweCAwO1xcbiAgYm9yZGVyLXRvcC1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBsZWZ0OiA1MCU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcFJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiAxNSU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRUb3AgLnJjLXRvb2x0aXAtYXJyb3csXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDRweDtcXG4gIG1hcmdpbi10b3A6IC01cHg7XFxuICBib3JkZXItd2lkdGg6IDVweCA1cHggNXB4IDA7XFxuICBib3JkZXItcmlnaHQtY29sb3I6ICMzNzM3Mzc7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0VG9wIC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogMTUlO1xcbiAgbWFyZ2luLXRvcDogMDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGJvdHRvbTogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICByaWdodDogNHB4O1xcbiAgbWFyZ2luLXRvcDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDAgNXB4IDVweDtcXG4gIGJvcmRlci1sZWZ0LWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWxlZnRUb3AgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiAxNSU7XFxuICBtYXJnaW4tdG9wOiAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tTGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiA0cHg7XFxuICBtYXJnaW4tbGVmdDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogMCA1cHggNXB4O1xcbiAgYm9yZGVyLWJvdHRvbS1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBsZWZ0OiA1MCU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21MZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbVJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiAxNSU7XFxufVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///467\n')},645:module=>{"use strict";eval('\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = "";\n var needLayer = typeof item[5] !== "undefined";\n if (item[4]) {\n content += "@supports (".concat(item[4], ") {");\n }\n if (item[2]) {\n content += "@media ".concat(item[2], " {");\n }\n if (needLayer) {\n content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += "}";\n }\n if (item[2]) {\n content += "}";\n }\n if (item[4]) {\n content += "}";\n }\n return content;\n }).join("");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === "string") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== "undefined") {\n if (typeof item[5] === "undefined") {\n item[5] = layer;\n } else {\n item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = "".concat(supports);\n } else {\n item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQ1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0EscUZBQXFGO0FBQ3JGO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixpQkFBaUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzRkFBc0YscUJBQXFCO0FBQzNHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixpREFBaUQscUJBQXFCO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzREFBc0QscUJBQXFCO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzPzI0ZmIiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qXG4gIE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4gIEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKSB7XG4gIHZhciBsaXN0ID0gW107XG5cbiAgLy8gcmV0dXJuIHRoZSBsaXN0IG9mIG1vZHVsZXMgYXMgY3NzIHN0cmluZ1xuICBsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICB2YXIgY29udGVudCA9IFwiXCI7XG4gICAgICB2YXIgbmVlZExheWVyID0gdHlwZW9mIGl0ZW1bNV0gIT09IFwidW5kZWZpbmVkXCI7XG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwiQHN1cHBvcnRzIChcIi5jb25jYXQoaXRlbVs0XSwgXCIpIHtcIik7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICBjb250ZW50ICs9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpO1xuICAgICAgfVxuICAgICAgaWYgKG5lZWRMYXllcikge1xuICAgICAgICBjb250ZW50ICs9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIik7XG4gICAgICB9XG4gICAgICBjb250ZW50ICs9IGNzc1dpdGhNYXBwaW5nVG9TdHJpbmcoaXRlbSk7XG4gICAgICBpZiAobmVlZExheWVyKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZW1bNF0pIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZW50O1xuICAgIH0pLmpvaW4oXCJcIik7XG4gIH07XG5cbiAgLy8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcbiAgbGlzdC5pID0gZnVuY3Rpb24gaShtb2R1bGVzLCBtZWRpYSwgZGVkdXBlLCBzdXBwb3J0cywgbGF5ZXIpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZXMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIG1vZHVsZXMgPSBbW251bGwsIG1vZHVsZXMsIHVuZGVmaW5lZF1dO1xuICAgIH1cbiAgICB2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xuICAgIGlmIChkZWR1cGUpIHtcbiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgdGhpcy5sZW5ndGg7IGsrKykge1xuICAgICAgICB2YXIgaWQgPSB0aGlzW2tdWzBdO1xuICAgICAgICBpZiAoaWQgIT0gbnVsbCkge1xuICAgICAgICAgIGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHZhciBfayA9IDA7IF9rIDwgbW9kdWxlcy5sZW5ndGg7IF9rKyspIHtcbiAgICAgIHZhciBpdGVtID0gW10uY29uY2F0KG1vZHVsZXNbX2tdKTtcbiAgICAgIGlmIChkZWR1cGUgJiYgYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpdGVtWzBdXSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbGF5ZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtWzVdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBsYXllclwiLmNvbmNhdChpdGVtWzVdLmxlbmd0aCA+IDAgPyBcIiBcIi5jb25jYXQoaXRlbVs1XSkgOiBcIlwiLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVkaWEpIHtcbiAgICAgICAgaWYgKCFpdGVtWzJdKSB7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBtZWRpYSBcIi5jb25jYXQoaXRlbVsyXSwgXCIge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bMl0gPSBtZWRpYTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN1cHBvcnRzKSB7XG4gICAgICAgIGlmICghaXRlbVs0XSkge1xuICAgICAgICAgIGl0ZW1bNF0gPSBcIlwiLmNvbmNhdChzdXBwb3J0cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQHN1cHBvcnRzIChcIi5jb25jYXQoaXRlbVs0XSwgXCIpIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzRdID0gc3VwcG9ydHM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxpc3QucHVzaChpdGVtKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBsaXN0O1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///645\n')},537:module=>{"use strict";eval('\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === "function") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n var sourceMapping = "/*# ".concat(data, " */");\n return [content].concat([sourceMapping]).join("\\n");\n }\n return [content].join("\\n");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTM3LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsY0FBYztBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanM/YWYxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlbSkge1xuICB2YXIgY29udGVudCA9IGl0ZW1bMV07XG4gIHZhciBjc3NNYXBwaW5nID0gaXRlbVszXTtcbiAgaWYgKCFjc3NNYXBwaW5nKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cbiAgaWYgKHR5cGVvZiBidG9hID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB2YXIgYmFzZTY0ID0gYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoY3NzTWFwcGluZykpKSk7XG4gICAgdmFyIGRhdGEgPSBcInNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LFwiLmNvbmNhdChiYXNlNjQpO1xuICAgIHZhciBzb3VyY2VNYXBwaW5nID0gXCIvKiMgXCIuY29uY2F0KGRhdGEsIFwiICovXCIpO1xuICAgIHJldHVybiBbY29udGVudF0uY29uY2F0KFtzb3VyY2VNYXBwaW5nXSkuam9pbihcIlxcblwiKTtcbiAgfVxuICByZXR1cm4gW2NvbnRlbnRdLmpvaW4oXCJcXG5cIik7XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///537\n')},543:(__unused_webpack_module,exports)=>{"use strict";eval("var __webpack_unused_export__;\n\n\n__webpack_unused_export__ = ({\n value: true\n});\nexports.Z = void 0;\nvar raf = function raf(callback) {\n return +setTimeout(callback, 16);\n};\nvar caf = function caf(num) {\n return clearTimeout(num);\n};\nif (typeof window !== 'undefined' && 'requestAnimationFrame' in window) {\n raf = function raf(callback) {\n return window.requestAnimationFrame(callback);\n };\n caf = function caf(handle) {\n return window.cancelAnimationFrame(handle);\n };\n}\nvar rafUUID = 0;\nvar rafIds = new Map();\nfunction cleanup(id) {\n rafIds.delete(id);\n}\nvar wrapperRaf = function wrapperRaf(callback) {\n var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n rafUUID += 1;\n var id = rafUUID;\n function callRef(leftTimes) {\n if (leftTimes === 0) {\n // Clean up\n cleanup(id);\n\n // Trigger\n callback();\n } else {\n // Next raf\n var realId = raf(function () {\n callRef(leftTimes - 1);\n });\n\n // Bind real raf id\n rafIds.set(id, realId);\n }\n }\n callRef(times);\n return id;\n};\nwrapperRaf.cancel = function (id) {\n var realId = rafIds.get(id);\n cleanup(realId);\n return caf(realId);\n};\nvar _default = wrapperRaf;\nexports.Z = _default;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQzLmpzIiwibWFwcGluZ3MiOiI7QUFBYTs7QUFFYiw2QkFBNkM7QUFDN0M7QUFDQSxDQUFDLENBQUM7QUFDRixTQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9saWIvcmFmLmpzPzZmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG52YXIgcmFmID0gZnVuY3Rpb24gcmFmKGNhbGxiYWNrKSB7XG4gIHJldHVybiArc2V0VGltZW91dChjYWxsYmFjaywgMTYpO1xufTtcbnZhciBjYWYgPSBmdW5jdGlvbiBjYWYobnVtKSB7XG4gIHJldHVybiBjbGVhclRpbWVvdXQobnVtKTtcbn07XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ3JlcXVlc3RBbmltYXRpb25GcmFtZScgaW4gd2luZG93KSB7XG4gIHJhZiA9IGZ1bmN0aW9uIHJhZihjYWxsYmFjaykge1xuICAgIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNhbGxiYWNrKTtcbiAgfTtcbiAgY2FmID0gZnVuY3Rpb24gY2FmKGhhbmRsZSkge1xuICAgIHJldHVybiB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlKTtcbiAgfTtcbn1cbnZhciByYWZVVUlEID0gMDtcbnZhciByYWZJZHMgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBjbGVhbnVwKGlkKSB7XG4gIHJhZklkcy5kZWxldGUoaWQpO1xufVxudmFyIHdyYXBwZXJSYWYgPSBmdW5jdGlvbiB3cmFwcGVyUmFmKGNhbGxiYWNrKSB7XG4gIHZhciB0aW1lcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMTtcbiAgcmFmVVVJRCArPSAxO1xuICB2YXIgaWQgPSByYWZVVUlEO1xuICBmdW5jdGlvbiBjYWxsUmVmKGxlZnRUaW1lcykge1xuICAgIGlmIChsZWZ0VGltZXMgPT09IDApIHtcbiAgICAgIC8vIENsZWFuIHVwXG4gICAgICBjbGVhbnVwKGlkKTtcblxuICAgICAgLy8gVHJpZ2dlclxuICAgICAgY2FsbGJhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmV4dCByYWZcbiAgICAgIHZhciByZWFsSWQgPSByYWYoZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsUmVmKGxlZnRUaW1lcyAtIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEJpbmQgcmVhbCByYWYgaWRcbiAgICAgIHJhZklkcy5zZXQoaWQsIHJlYWxJZCk7XG4gICAgfVxuICB9XG4gIGNhbGxSZWYodGltZXMpO1xuICByZXR1cm4gaWQ7XG59O1xud3JhcHBlclJhZi5jYW5jZWwgPSBmdW5jdGlvbiAoaWQpIHtcbiAgdmFyIHJlYWxJZCA9IHJhZklkcy5nZXQoaWQpO1xuICBjbGVhbnVwKHJlYWxJZCk7XG4gIHJldHVybiBjYWYocmVhbElkKTtcbn07XG52YXIgX2RlZmF1bHQgPSB3cmFwcGVyUmFmO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///543\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")},921:(__unused_webpack_module,exports)=>{"use strict";eval('var __webpack_unused_export__;\n/** @license React v16.13.1\n * react-is.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\nvar b="function"===typeof Symbol&&Symbol.for,c=b?Symbol.for("react.element"):60103,d=b?Symbol.for("react.portal"):60106,e=b?Symbol.for("react.fragment"):60107,f=b?Symbol.for("react.strict_mode"):60108,g=b?Symbol.for("react.profiler"):60114,h=b?Symbol.for("react.provider"):60109,k=b?Symbol.for("react.context"):60110,l=b?Symbol.for("react.async_mode"):60111,m=b?Symbol.for("react.concurrent_mode"):60111,n=b?Symbol.for("react.forward_ref"):60112,p=b?Symbol.for("react.suspense"):60113,q=b?\nSymbol.for("react.suspense_list"):60120,r=b?Symbol.for("react.memo"):60115,t=b?Symbol.for("react.lazy"):60116,v=b?Symbol.for("react.block"):60121,w=b?Symbol.for("react.fundamental"):60117,x=b?Symbol.for("react.responder"):60118,y=b?Symbol.for("react.scope"):60119;\nfunction z(a){if("object"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}__webpack_unused_export__=l;__webpack_unused_export__=m;__webpack_unused_export__=k;__webpack_unused_export__=h;__webpack_unused_export__=c;__webpack_unused_export__=n;__webpack_unused_export__=e;__webpack_unused_export__=t;__webpack_unused_export__=r;__webpack_unused_export__=d;\n__webpack_unused_export__=g;__webpack_unused_export__=f;__webpack_unused_export__=p;__webpack_unused_export__=function(a){return A(a)||z(a)===l};__webpack_unused_export__=A;__webpack_unused_export__=function(a){return z(a)===k};__webpack_unused_export__=function(a){return z(a)===h};__webpack_unused_export__=function(a){return"object"===typeof a&&null!==a&&a.$$typeof===c};__webpack_unused_export__=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};__webpack_unused_export__=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};__webpack_unused_export__=function(a){return z(a)===d};__webpack_unused_export__=function(a){return z(a)===g};__webpack_unused_export__=function(a){return z(a)===f};__webpack_unused_export__=function(a){return z(a)===p};\n__webpack_unused_export__=function(a){return"string"===typeof a||"function"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||"object"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};__webpack_unused_export__=z;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTIxLmpzIiwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVhO0FBQ2I7QUFDQSxjQUFjLGtDQUFrQyxpQkFBaUIsVUFBVSwwQkFBMEIsbURBQW1ELGtDQUFrQyw0Q0FBNEMsa0JBQWtCLGtCQUFrQixjQUFjLGdCQUFnQix5QkFBaUIsR0FBRyx5QkFBc0IsR0FBRyx5QkFBdUIsR0FBRyx5QkFBdUIsR0FBRyx5QkFBZSxHQUFHLHlCQUFrQixHQUFHLHlCQUFnQixHQUFHLHlCQUFZLEdBQUcseUJBQVksR0FBRyx5QkFBYztBQUMvZSx5QkFBZ0IsR0FBRyx5QkFBa0IsR0FBRyx5QkFBZ0IsR0FBRyx5QkFBbUIsYUFBYSx1QkFBdUIseUJBQXdCLEdBQUcseUJBQXlCLGFBQWEsaUJBQWlCLHlCQUF5QixhQUFhLGlCQUFpQix5QkFBaUIsYUFBYSxxREFBcUQseUJBQW9CLGFBQWEsaUJBQWlCLGtCQUFrQixhQUFhLGlCQUFpQix5QkFBYyxhQUFhO0FBQzNjLGNBQWMsYUFBYSxpQkFBaUIseUJBQWdCLGFBQWEsaUJBQWlCLHlCQUFrQixhQUFhLGlCQUFpQix5QkFBb0IsYUFBYSxpQkFBaUIseUJBQWtCLGFBQWE7QUFDM04seUJBQTBCLGFBQWEsNlFBQTZRLHlCQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWlzL2Nqcy9yZWFjdC1pcy5wcm9kdWN0aW9uLm1pbi5qcz9hOTNkIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbGljZW5zZSBSZWFjdCB2MTYuMTMuMVxuICogcmVhY3QtaXMucHJvZHVjdGlvbi5taW4uanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7dmFyIGI9XCJmdW5jdGlvblwiPT09dHlwZW9mIFN5bWJvbCYmU3ltYm9sLmZvcixjPWI/U3ltYm9sLmZvcihcInJlYWN0LmVsZW1lbnRcIik6NjAxMDMsZD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5wb3J0YWxcIik6NjAxMDYsZT1iP1N5bWJvbC5mb3IoXCJyZWFjdC5mcmFnbWVudFwiKTo2MDEwNyxmPWI/U3ltYm9sLmZvcihcInJlYWN0LnN0cmljdF9tb2RlXCIpOjYwMTA4LGc9Yj9TeW1ib2wuZm9yKFwicmVhY3QucHJvZmlsZXJcIik6NjAxMTQsaD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5wcm92aWRlclwiKTo2MDEwOSxrPWI/U3ltYm9sLmZvcihcInJlYWN0LmNvbnRleHRcIik6NjAxMTAsbD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5hc3luY19tb2RlXCIpOjYwMTExLG09Yj9TeW1ib2wuZm9yKFwicmVhY3QuY29uY3VycmVudF9tb2RlXCIpOjYwMTExLG49Yj9TeW1ib2wuZm9yKFwicmVhY3QuZm9yd2FyZF9yZWZcIik6NjAxMTIscD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5zdXNwZW5zZVwiKTo2MDExMyxxPWI/XG5TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VfbGlzdFwiKTo2MDEyMCxyPWI/U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIik6NjAxMTUsdD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5sYXp5XCIpOjYwMTE2LHY9Yj9TeW1ib2wuZm9yKFwicmVhY3QuYmxvY2tcIik6NjAxMjEsdz1iP1N5bWJvbC5mb3IoXCJyZWFjdC5mdW5kYW1lbnRhbFwiKTo2MDExNyx4PWI/U3ltYm9sLmZvcihcInJlYWN0LnJlc3BvbmRlclwiKTo2MDExOCx5PWI/U3ltYm9sLmZvcihcInJlYWN0LnNjb3BlXCIpOjYwMTE5O1xuZnVuY3Rpb24geihhKXtpZihcIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hKXt2YXIgdT1hLiQkdHlwZW9mO3N3aXRjaCh1KXtjYXNlIGM6c3dpdGNoKGE9YS50eXBlLGEpe2Nhc2UgbDpjYXNlIG06Y2FzZSBlOmNhc2UgZzpjYXNlIGY6Y2FzZSBwOnJldHVybiBhO2RlZmF1bHQ6c3dpdGNoKGE9YSYmYS4kJHR5cGVvZixhKXtjYXNlIGs6Y2FzZSBuOmNhc2UgdDpjYXNlIHI6Y2FzZSBoOnJldHVybiBhO2RlZmF1bHQ6cmV0dXJuIHV9fWNhc2UgZDpyZXR1cm4gdX19fWZ1bmN0aW9uIEEoYSl7cmV0dXJuIHooYSk9PT1tfWV4cG9ydHMuQXN5bmNNb2RlPWw7ZXhwb3J0cy5Db25jdXJyZW50TW9kZT1tO2V4cG9ydHMuQ29udGV4dENvbnN1bWVyPWs7ZXhwb3J0cy5Db250ZXh0UHJvdmlkZXI9aDtleHBvcnRzLkVsZW1lbnQ9YztleHBvcnRzLkZvcndhcmRSZWY9bjtleHBvcnRzLkZyYWdtZW50PWU7ZXhwb3J0cy5MYXp5PXQ7ZXhwb3J0cy5NZW1vPXI7ZXhwb3J0cy5Qb3J0YWw9ZDtcbmV4cG9ydHMuUHJvZmlsZXI9ZztleHBvcnRzLlN0cmljdE1vZGU9ZjtleHBvcnRzLlN1c3BlbnNlPXA7ZXhwb3J0cy5pc0FzeW5jTW9kZT1mdW5jdGlvbihhKXtyZXR1cm4gQShhKXx8eihhKT09PWx9O2V4cG9ydHMuaXNDb25jdXJyZW50TW9kZT1BO2V4cG9ydHMuaXNDb250ZXh0Q29uc3VtZXI9ZnVuY3Rpb24oYSl7cmV0dXJuIHooYSk9PT1rfTtleHBvcnRzLmlzQ29udGV4dFByb3ZpZGVyPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09aH07ZXhwb3J0cy5pc0VsZW1lbnQ9ZnVuY3Rpb24oYSl7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZudWxsIT09YSYmYS4kJHR5cGVvZj09PWN9O2V4cG9ydHMuaXNGb3J3YXJkUmVmPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09bn07ZXhwb3J0cy5pc0ZyYWdtZW50PWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09ZX07ZXhwb3J0cy5pc0xhenk9ZnVuY3Rpb24oYSl7cmV0dXJuIHooYSk9PT10fTtcbmV4cG9ydHMuaXNNZW1vPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09cn07ZXhwb3J0cy5pc1BvcnRhbD1mdW5jdGlvbihhKXtyZXR1cm4geihhKT09PWR9O2V4cG9ydHMuaXNQcm9maWxlcj1mdW5jdGlvbihhKXtyZXR1cm4geihhKT09PWd9O2V4cG9ydHMuaXNTdHJpY3RNb2RlPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09Zn07ZXhwb3J0cy5pc1N1c3BlbnNlPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09cH07XG5leHBvcnRzLmlzVmFsaWRFbGVtZW50VHlwZT1mdW5jdGlvbihhKXtyZXR1cm5cInN0cmluZ1wiPT09dHlwZW9mIGF8fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBhfHxhPT09ZXx8YT09PW18fGE9PT1nfHxhPT09Znx8YT09PXB8fGE9PT1xfHxcIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hJiYoYS4kJHR5cGVvZj09PXR8fGEuJCR0eXBlb2Y9PT1yfHxhLiQkdHlwZW9mPT09aHx8YS4kJHR5cGVvZj09PWt8fGEuJCR0eXBlb2Y9PT1ufHxhLiQkdHlwZW9mPT09d3x8YS4kJHR5cGVvZj09PXh8fGEuJCR0eXBlb2Y9PT15fHxhLiQkdHlwZW9mPT09dil9O2V4cG9ydHMudHlwZU9mPXo7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///921\n')},864:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(921);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODY0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx5Q0FBNEQ7QUFDOUQsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QtaXMvaW5kZXguanM/NGNlYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtaXMucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtaXMuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///864\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")},379:module=>{"use strict";eval('\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = "".concat(id, " ").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQix3QkFBd0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsaUJBQWlCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsNEJBQTRCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsNkJBQTZCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzPzJkYmEiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBzdHlsZXNJbkRPTSA9IFtdO1xuZnVuY3Rpb24gZ2V0SW5kZXhCeUlkZW50aWZpZXIoaWRlbnRpZmllcikge1xuICB2YXIgcmVzdWx0ID0gLTE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3R5bGVzSW5ET00ubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc3R5bGVzSW5ET01baV0uaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgcmVzdWx0ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbW9kdWxlc1RvRG9tKGxpc3QsIG9wdGlvbnMpIHtcbiAgdmFyIGlkQ291bnRNYXAgPSB7fTtcbiAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXTtcbiAgICB2YXIgaWQgPSBvcHRpb25zLmJhc2UgPyBpdGVtWzBdICsgb3B0aW9ucy5iYXNlIDogaXRlbVswXTtcbiAgICB2YXIgY291bnQgPSBpZENvdW50TWFwW2lkXSB8fCAwO1xuICAgIHZhciBpZGVudGlmaWVyID0gXCJcIi5jb25jYXQoaWQsIFwiIFwiKS5jb25jYXQoY291bnQpO1xuICAgIGlkQ291bnRNYXBbaWRdID0gY291bnQgKyAxO1xuICAgIHZhciBpbmRleEJ5SWRlbnRpZmllciA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgIHZhciBvYmogPSB7XG4gICAgICBjc3M6IGl0ZW1bMV0sXG4gICAgICBtZWRpYTogaXRlbVsyXSxcbiAgICAgIHNvdXJjZU1hcDogaXRlbVszXSxcbiAgICAgIHN1cHBvcnRzOiBpdGVtWzRdLFxuICAgICAgbGF5ZXI6IGl0ZW1bNV1cbiAgICB9O1xuICAgIGlmIChpbmRleEJ5SWRlbnRpZmllciAhPT0gLTEpIHtcbiAgICAgIHN0eWxlc0luRE9NW2luZGV4QnlJZGVudGlmaWVyXS5yZWZlcmVuY2VzKys7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0udXBkYXRlcihvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXBkYXRlciA9IGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5ieUluZGV4ID0gaTtcbiAgICAgIHN0eWxlc0luRE9NLnNwbGljZShpLCAwLCB7XG4gICAgICAgIGlkZW50aWZpZXI6IGlkZW50aWZpZXIsXG4gICAgICAgIHVwZGF0ZXI6IHVwZGF0ZXIsXG4gICAgICAgIHJlZmVyZW5jZXM6IDFcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50aWZpZXIpO1xuICB9XG4gIHJldHVybiBpZGVudGlmaWVycztcbn1cbmZ1bmN0aW9uIGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpIHtcbiAgdmFyIGFwaSA9IG9wdGlvbnMuZG9tQVBJKG9wdGlvbnMpO1xuICBhcGkudXBkYXRlKG9iaik7XG4gIHZhciB1cGRhdGVyID0gZnVuY3Rpb24gdXBkYXRlcihuZXdPYmopIHtcbiAgICBpZiAobmV3T2JqKSB7XG4gICAgICBpZiAobmV3T2JqLmNzcyA9PT0gb2JqLmNzcyAmJiBuZXdPYmoubWVkaWEgPT09IG9iai5tZWRpYSAmJiBuZXdPYmouc291cmNlTWFwID09PSBvYmouc291cmNlTWFwICYmIG5ld09iai5zdXBwb3J0cyA9PT0gb2JqLnN1cHBvcnRzICYmIG5ld09iai5sYXllciA9PT0gb2JqLmxheWVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGFwaS51cGRhdGUob2JqID0gbmV3T2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXBpLnJlbW92ZSgpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHVwZGF0ZXI7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChsaXN0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBsaXN0ID0gbGlzdCB8fCBbXTtcbiAgdmFyIGxhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZShuZXdMaXN0KSB7XG4gICAgbmV3TGlzdCA9IG5ld0xpc3QgfHwgW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYXN0SWRlbnRpZmllcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW2ldO1xuICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXhCeUlkZW50aWZpZXIoaWRlbnRpZmllcik7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleF0ucmVmZXJlbmNlcy0tO1xuICAgIH1cbiAgICB2YXIgbmV3TGFzdElkZW50aWZpZXJzID0gbW9kdWxlc1RvRG9tKG5ld0xpc3QsIG9wdGlvbnMpO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBsYXN0SWRlbnRpZmllcnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgX2lkZW50aWZpZXIgPSBsYXN0SWRlbnRpZmllcnNbX2ldO1xuICAgICAgdmFyIF9pbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKF9pZGVudGlmaWVyKTtcbiAgICAgIGlmIChzdHlsZXNJbkRPTVtfaW5kZXhdLnJlZmVyZW5jZXMgPT09IDApIHtcbiAgICAgICAgc3R5bGVzSW5ET01bX2luZGV4XS51cGRhdGVyKCk7XG4gICAgICAgIHN0eWxlc0luRE9NLnNwbGljZShfaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBsYXN0SWRlbnRpZmllcnMgPSBuZXdMYXN0SWRlbnRpZmllcnM7XG4gIH07XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///379\n')},569:module=>{"use strict";eval('\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === "undefined") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error("Couldn\'t find a style target. This probably means that the value for the \'insert\' parameter is invalid.");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTY5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanM/YjIxNCJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpO1xuXG4gICAgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcbiAgICBpZiAod2luZG93LkhUTUxJRnJhbWVFbGVtZW50ICYmIHN0eWxlVGFyZ2V0IGluc3RhbmNlb2Ygd2luZG93LkhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFjY2VzcyB0byBpZnJhbWUgaXMgYmxvY2tlZFxuICAgICAgICAvLyBkdWUgdG8gY3Jvc3Mtb3JpZ2luIHJlc3RyaWN0aW9uc1xuICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpc3RhbmJ1bCBpZ25vcmUgbmV4dFxuICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG4gIHJldHVybiBtZW1vW3RhcmdldF07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0QnlTZWxlY3RvcihpbnNlcnQsIHN0eWxlKSB7XG4gIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoaW5zZXJ0KTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG4gIHRhcmdldC5hcHBlbmRDaGlsZChzdHlsZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydEJ5U2VsZWN0b3I7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///569\n')},216:module=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement("style");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE2LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanM/ZGU2YyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBpbnNlcnRTdHlsZUVsZW1lbnQob3B0aW9ucykge1xuICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgb3B0aW9ucy5zZXRBdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMuYXR0cmlidXRlcyk7XG4gIG9wdGlvbnMuaW5zZXJ0KGVsZW1lbnQsIG9wdGlvbnMub3B0aW9ucyk7XG4gIHJldHVybiBlbGVtZW50O1xufVxubW9kdWxlLmV4cG9ydHMgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///216\n')},565:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute("nonce", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTY1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQSxjQUFjLEtBQXdDLEdBQUcsc0JBQWlCLEdBQUcsQ0FBSTtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzP2RkY2UiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzKHN0eWxlRWxlbWVudCkge1xuICB2YXIgbm9uY2UgPSB0eXBlb2YgX193ZWJwYWNrX25vbmNlX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3dlYnBhY2tfbm9uY2VfXyA6IG51bGw7XG4gIGlmIChub25jZSkge1xuICAgIHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBub25jZSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///565\n')},795:module=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = "";\n if (obj.supports) {\n css += "@supports (".concat(obj.supports, ") {");\n }\n if (obj.media) {\n css += "@media ".concat(obj.media, " {");\n }\n var needLayer = typeof obj.layer !== "undefined";\n if (needLayer) {\n css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");\n }\n css += obj.css;\n if (needLayer) {\n css += "}";\n }\n if (obj.media) {\n css += "}";\n }\n if (obj.supports) {\n css += "}";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== "undefined") {\n css += "\\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === "undefined") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xEO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanM/ZTQ3OSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaikge1xuICB2YXIgY3NzID0gXCJcIjtcbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KG9iai5zdXBwb3J0cywgXCIpIHtcIik7XG4gIH1cbiAgaWYgKG9iai5tZWRpYSkge1xuICAgIGNzcyArPSBcIkBtZWRpYSBcIi5jb25jYXQob2JqLm1lZGlhLCBcIiB7XCIpO1xuICB9XG4gIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2Ygb2JqLmxheWVyICE9PSBcInVuZGVmaW5lZFwiO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwiQGxheWVyXCIuY29uY2F0KG9iai5sYXllci5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KG9iai5sYXllcikgOiBcIlwiLCBcIiB7XCIpO1xuICB9XG4gIGNzcyArPSBvYmouY3NzO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICB2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcbiAgaWYgKHNvdXJjZU1hcCAmJiB0eXBlb2YgYnRvYSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIuY29uY2F0KGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSksIFwiICovXCIpO1xuICB9XG5cbiAgLy8gRm9yIG9sZCBJRVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgICovXG4gIG9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0oY3NzLCBzdHlsZUVsZW1lbnQsIG9wdGlvbnMub3B0aW9ucyk7XG59XG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KSB7XG4gIC8vIGlzdGFuYnVsIGlnbm9yZSBpZlxuICBpZiAoc3R5bGVFbGVtZW50LnBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3R5bGVFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50KTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBkb21BUEkob3B0aW9ucykge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKCkge30sXG4gICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHt9XG4gICAgfTtcbiAgfVxuICB2YXIgc3R5bGVFbGVtZW50ID0gb3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQob3B0aW9ucyk7XG4gIHJldHVybiB7XG4gICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUob2JqKSB7XG4gICAgICBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaik7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgICAgIHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpO1xuICAgIH1cbiAgfTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZG9tQVBJOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///795\n')},589:module=>{"use strict";eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTg5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanM/MWRkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBzdHlsZVRhZ1RyYW5zZm9ybShjc3MsIHN0eWxlRWxlbWVudCkge1xuICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcbiAgICBzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGVFbGVtZW50LnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgc3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHN0eWxlVGFnVHJhbnNmb3JtOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///589\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__={},leafPrototypes,getProto;function __webpack_require__(I){var g=__webpack_module_cache__[I];if(void 0!==g)return g.exports;var n=__webpack_module_cache__[I]={id: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},getProto=Object.getPrototypeOf?I=>Object.getPrototypeOf(I):I=>I.__proto__,__webpack_require__.t=function(I,g){if(1&g&&(I=this(I)),8&g)return I;if("object"==typeof I&&I){if(4&g&&I.__esModule)return I;if(16&g&&"function"==typeof I.then)return I}var n=Object.create(null);__webpack_require__.r(n);var t={};leafPrototypes=leafPrototypes||[null,getProto({}),getProto([]),getProto(getProto)];for(var e=2&g&&I;"object"==typeof e&&!~leafPrototypes.indexOf(e);e=getProto(e))Object.getOwnPropertyNames(e).forEach((g=>t[g]=()=>I[g]));return t.default=()=>I,__webpack_require__.d(n,t),n},__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__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(I){if("object"==typeof window)return window}}(),__webpack_require__.o=(I,g)=>Object.prototype.hasOwnProperty.call(I,g),__webpack_require__.r=I=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(I,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(I,"__esModule",{value:!0})},__webpack_require__.nc=void 0;var __webpack_exports__=__webpack_require__(905)})();
\ 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")},905:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval('\n// NAMESPACE OBJECT: ./src/lib/instruments.js\nvar instruments_namespaceObject = {};\n__webpack_require__.r(instruments_namespaceObject);\n__webpack_require__.d(instruments_namespaceObject, {\n "Cymbal": () => (Cymbal),\n "Drums": () => (Drums),\n "Hat": () => (Hat),\n "Kalimba": () => (Kalimba),\n "Kick": () => (Kick),\n "Perc": () => (Perc),\n "Snare": () => (Snare),\n "Tom": () => (Tom)\n});\n\n// EXTERNAL MODULE: ./node_modules/react/index.js\nvar react = __webpack_require__(294);\nvar react_namespaceObject = /*#__PURE__*/__webpack_require__.t(react, 2);\n// EXTERNAL MODULE: ./node_modules/react-dom/client.js\nvar client = __webpack_require__(745);\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/version.js\nconst version = "14.7.77";\n//# sourceMappingURL=version.js.map\n// EXTERNAL MODULE: ./node_modules/automation-events/build/es5/bundle.js\nvar bundle = __webpack_require__(382);\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/abort-error.js\nconst createAbortError = () => new DOMException(\'\', \'AbortError\');\n//# sourceMappingURL=abort-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-active-input-connection-to-audio-node.js\nconst createAddActiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (activeInputs, source, [output, input, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs[input], [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n };\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-node-connections.js\nconst createAddAudioNodeConnections = (audioNodeConnectionsStore) => {\n return (audioNode, audioNodeRenderer, nativeAudioNode) => {\n const activeInputs = [];\n for (let i = 0; i < nativeAudioNode.numberOfInputs; i += 1) {\n activeInputs.push(new Set());\n }\n audioNodeConnectionsStore.set(audioNode, {\n activeInputs,\n outputs: new Set(),\n passiveInputs: new WeakMap(),\n renderer: audioNodeRenderer\n });\n };\n};\n//# sourceMappingURL=add-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-param-connections.js\nconst createAddAudioParamConnections = (audioParamConnectionsStore) => {\n return (audioParam, audioParamRenderer) => {\n audioParamConnectionsStore.set(audioParam, { activeInputs: new Set(), passiveInputs: new WeakMap(), renderer: audioParamRenderer });\n };\n};\n//# sourceMappingURL=add-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/globals.js\nconst ACTIVE_AUDIO_NODE_STORE = new WeakSet();\nconst AUDIO_NODE_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_NODE_STORE = new WeakMap();\nconst AUDIO_PARAM_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_PARAM_STORE = new WeakMap();\nconst CONTEXT_STORE = new WeakMap();\nconst EVENT_LISTENERS = new WeakMap();\nconst CYCLE_COUNTERS = new WeakMap();\n// This clunky name is borrowed from the spec. :-)\nconst NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS = new WeakMap();\nconst NODE_TO_PROCESSOR_MAPS = new WeakMap();\n//# sourceMappingURL=globals.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-constructible.js\nconst handler = {\n construct() {\n return handler;\n }\n};\nconst isConstructible = (constructible) => {\n try {\n const proxy = new Proxy(constructible, handler);\n new proxy(); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=is-constructible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/split-import-statements.js\n/*\n * This massive regex tries to cover all the following cases.\n *\n * import \'./path\';\n * import defaultImport from \'./path\';\n * import { namedImport } from \'./path\';\n * import { namedImport as renamendImport } from \'./path\';\n * import * as namespaceImport from \'./path\';\n * import defaultImport, { namedImport } from \'./path\';\n * import defaultImport, { namedImport as renamendImport } from \'./path\';\n * import defaultImport, * as namespaceImport from \'./path\';\n */\nconst IMPORT_STATEMENT_REGEX = /^import(?:(?:[\\s]+[\\w]+|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\{[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?(?:[\\s]*,[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?)*[\\s]*}|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\*[\\s]+as[\\s]+[\\w]+)[\\s]+from)?(?:[\\s]*)("([^"\\\\]|\\\\.)+"|\'([^\'\\\\]|\\\\.)+\')(?:[\\s]*);?/; // tslint:disable-line:max-line-length\nconst splitImportStatements = (source, url) => {\n const importStatements = [];\n let sourceWithoutImportStatements = source.replace(/^[\\s]+/, \'\');\n let result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n while (result !== null) {\n const unresolvedUrl = result[1].slice(1, -1);\n const importStatementWithResolvedUrl = result[0]\n .replace(/([\\s]+)?;?$/, \'\')\n .replace(unresolvedUrl, new URL(unresolvedUrl, url).toString());\n importStatements.push(importStatementWithResolvedUrl);\n sourceWithoutImportStatements = sourceWithoutImportStatements.slice(result[0].length).replace(/^[\\s]+/, \'\');\n result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n }\n return [importStatements.join(\';\'), sourceWithoutImportStatements];\n};\n//# sourceMappingURL=split-import-statements.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-worklet-module.js\n\n\n\nconst verifyParameterDescriptors = (parameterDescriptors) => {\n if (parameterDescriptors !== undefined && !Array.isArray(parameterDescriptors)) {\n throw new TypeError(\'The parameterDescriptors property of given value for processorCtor is not an array.\');\n }\n};\nconst verifyProcessorCtor = (processorCtor) => {\n if (!isConstructible(processorCtor)) {\n throw new TypeError(\'The given value for processorCtor should be a constructor.\');\n }\n if (processorCtor.prototype === null || typeof processorCtor.prototype !== \'object\') {\n throw new TypeError(\'The given value for processorCtor should have a prototype.\');\n }\n};\nconst createAddAudioWorkletModule = (cacheTestResult, createNotSupportedError, evaluateSource, exposeCurrentFrameAndCurrentTime, fetchSource, getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, ongoingRequests, resolvedRequests, testAudioWorkletProcessorPostMessageSupport, window) => {\n let index = 0;\n return (context, moduleURL, options = { credentials: \'omit\' }) => {\n const resolvedRequestsOfContext = resolvedRequests.get(context);\n if (resolvedRequestsOfContext !== undefined && resolvedRequestsOfContext.has(moduleURL)) {\n return Promise.resolve();\n }\n const ongoingRequestsOfContext = ongoingRequests.get(context);\n if (ongoingRequestsOfContext !== undefined) {\n const promiseOfOngoingRequest = ongoingRequestsOfContext.get(moduleURL);\n if (promiseOfOngoingRequest !== undefined) {\n return promiseOfOngoingRequest;\n }\n }\n const nativeContext = getNativeContext(context);\n // Bug #59: Safari does not implement the audioWorklet property.\n const promise = nativeContext.audioWorklet === undefined\n ? fetchSource(moduleURL)\n .then(([source, absoluteUrl]) => {\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * This is the unminified version of the code used below:\n *\n * ```js\n * ${ importStatements };\n * ((a, b) => {\n * (a[b] = a[b] || [ ]).push(\n * (AudioWorkletProcessor, global, registerProcessor, sampleRate, self, window) => {\n * ${ sourceWithoutImportStatements }\n * }\n * );\n * })(window, \'_AWGS\');\n * ```\n */\n // tslint:disable-next-line:max-line-length\n const wrappedSource = `${importStatements};((a,b)=>{(a[b]=a[b]||[]).push((AudioWorkletProcessor,global,registerProcessor,sampleRate,self,window)=>{${sourceWithoutImportStatements}\n})})(window,\'_AWGS\')`;\n // @todo Evaluating the given source code is a possible security problem.\n return evaluateSource(wrappedSource);\n })\n .then(() => {\n const evaluateAudioWorkletGlobalScope = window._AWGS.pop();\n if (evaluateAudioWorkletGlobalScope === undefined) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n throw new SyntaxError();\n }\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => evaluateAudioWorkletGlobalScope(class AudioWorkletProcessor {\n }, undefined, (name, processorCtor) => {\n if (name.trim() === \'\') {\n throw createNotSupportedError();\n }\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n if (nodeNameToProcessorConstructorMap !== undefined) {\n if (nodeNameToProcessorConstructorMap.has(name)) {\n throw createNotSupportedError();\n }\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n nodeNameToProcessorConstructorMap.set(name, processorCtor);\n }\n else {\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.set(nativeContext, new Map([[name, processorCtor]]));\n }\n }, nativeContext.sampleRate, undefined, undefined));\n })\n : Promise.all([\n fetchSource(moduleURL),\n Promise.resolve(cacheTestResult(testAudioWorkletProcessorPostMessageSupport, testAudioWorkletProcessorPostMessageSupport))\n ]).then(([[source, absoluteUrl], isSupportingPostMessage]) => {\n const currentIndex = index + 1;\n index = currentIndex;\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * This is the unminified version of the code used below.\n *\n * ```js\n * class extends AudioWorkletProcessor {\n *\n * __buffers = new WeakSet();\n *\n * constructor () {\n * super();\n *\n * this.port.postMessage = ((postMessage) => {\n * return (message, transferables) => {\n * const filteredTransferables = (transferables)\n * ? transferables.filter((transferable) => !this.__buffers.has(transferable))\n * : transferables;\n *\n * return postMessage.call(this.port, message, filteredTransferables);\n * };\n * })(this.port.postMessage);\n * }\n * }\n * ```\n */\n const patchedAudioWorkletProcessor = isSupportingPostMessage\n ? \'AudioWorkletProcessor\'\n : \'class extends AudioWorkletProcessor {__b=new WeakSet();constructor(){super();(p=>p.postMessage=(q=>(m,t)=>q.call(p,m,t?t.filter(u=>!this.__b.has(u)):t))(p.postMessage))(this.port)}}\';\n /*\n * Bug #170: Chrome and Edge do call process() with an array with empty channelData for each input if no input is connected.\n *\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n *\n * This is the unminified version of the code used below:\n *\n * ```js\n * `${ importStatements };\n * ((AudioWorkletProcessor, registerProcessor) => {${ sourceWithoutImportStatements }\n * })(\n * ${ patchedAudioWorkletProcessor },\n * (name, processorCtor) => registerProcessor(name, class extends processorCtor {\n *\n * __collectBuffers = (array) => {\n * array.forEach((element) => this.__buffers.add(element.buffer));\n * };\n *\n * process (inputs, outputs, parameters) {\n * inputs.forEach(this.__collectBuffers);\n * outputs.forEach(this.__collectBuffers);\n * this.__collectBuffers(Object.values(parameters));\n *\n * return super.process(\n * (inputs.map((input) => input.some((channelData) => channelData.length === 0)) ? [ ] : input),\n * outputs,\n * parameters\n * );\n * }\n *\n * })\n * );\n *\n * registerProcessor(`__sac${currentIndex}`, class extends AudioWorkletProcessor{\n *\n * process () {\n * return false;\n * }\n *\n * })`\n * ```\n */\n const memberDefinition = isSupportingPostMessage ? \'\' : \'__c = (a) => a.forEach(e=>this.__b.add(e.buffer));\';\n const bufferRegistration = isSupportingPostMessage\n ? \'\'\n : \'i.forEach(this.__c);o.forEach(this.__c);this.__c(Object.values(p));\';\n const wrappedSource = `${importStatements};((AudioWorkletProcessor,registerProcessor)=>{${sourceWithoutImportStatements}\n})(${patchedAudioWorkletProcessor},(n,p)=>registerProcessor(n,class extends p{${memberDefinition}process(i,o,p){${bufferRegistration}return super.process(i.map(j=>j.some(k=>k.length===0)?[]:j),o,p)}}));registerProcessor(\'__sac${currentIndex}\',class extends AudioWorkletProcessor{process(){return !1}})`;\n const blob = new Blob([wrappedSource], { type: \'application/javascript; charset=utf-8\' });\n const url = URL.createObjectURL(blob);\n return nativeContext.audioWorklet\n .addModule(url, options)\n .then(() => {\n if (isNativeOfflineAudioContext(nativeContext)) {\n return nativeContext;\n }\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const backupOfflineAudioContext = getOrCreateBackupOfflineAudioContext(nativeContext);\n return backupOfflineAudioContext.audioWorklet.addModule(url, options).then(() => backupOfflineAudioContext);\n })\n .then((nativeContextOrBackupOfflineAudioContext) => {\n if (nativeAudioWorkletNodeConstructor === null) {\n throw new SyntaxError();\n }\n try {\n // Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n new nativeAudioWorkletNodeConstructor(nativeContextOrBackupOfflineAudioContext, `__sac${currentIndex}`); // tslint:disable-line:no-unused-expression\n }\n catch {\n throw new SyntaxError();\n }\n })\n .finally(() => URL.revokeObjectURL(url));\n });\n if (ongoingRequestsOfContext === undefined) {\n ongoingRequests.set(context, new Map([[moduleURL, promise]]));\n }\n else {\n ongoingRequestsOfContext.set(moduleURL, promise);\n }\n promise\n .then(() => {\n const updatedResolvedRequestsOfContext = resolvedRequests.get(context);\n if (updatedResolvedRequestsOfContext === undefined) {\n resolvedRequests.set(context, new Set([moduleURL]));\n }\n else {\n updatedResolvedRequestsOfContext.add(moduleURL);\n }\n })\n .finally(() => {\n const updatedOngoingRequestsOfContext = ongoingRequests.get(context);\n if (updatedOngoingRequestsOfContext !== undefined) {\n updatedOngoingRequestsOfContext.delete(moduleURL);\n }\n });\n return promise;\n };\n};\n//# sourceMappingURL=add-audio-worklet-module.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-value-for-key.js\nconst getValueForKey = (map, key) => {\n const value = map.get(key);\n if (value === undefined) {\n throw new Error(\'A value with the given key could not be found.\');\n }\n return value;\n};\n//# sourceMappingURL=get-value-for-key.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/pick-element-from-set.js\nconst pickElementFromSet = (set, predicate) => {\n const matchingElements = Array.from(set).filter(predicate);\n if (matchingElements.length > 1) {\n throw Error(\'More than one element was found.\');\n }\n if (matchingElements.length === 0) {\n throw Error(\'No element was found.\');\n }\n const [matchingElement] = matchingElements;\n set.delete(matchingElement);\n return matchingElement;\n};\n//# sourceMappingURL=pick-element-from-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-node.js\n\n\nconst deletePassiveInputConnectionToAudioNode = (passiveInputs, source, output, input) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-event-listeners-of-audio-node.js\n\n\nconst getEventListenersOfAudioNode = (audioNode) => {\n return getValueForKey(EVENT_LISTENERS, audioNode);\n};\n//# sourceMappingURL=get-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-active.js\n\n\nconst setInternalStateToActive = (audioNode) => {\n if (ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is already stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE.add(audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(true));\n};\n//# sourceMappingURL=set-internal-state-to-active.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-worklet-node.js\nconst isAudioWorkletNode = (audioNode) => {\n return \'port\' in audioNode;\n};\n//# sourceMappingURL=audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive.js\n\n\nconst setInternalStateToPassive = (audioNode) => {\n if (!ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is not stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE["delete"](audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(false));\n};\n//# sourceMappingURL=set-internal-state-to-passive.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive-when-necessary.js\n\n\n// Set the internalState of the audioNode to \'passive\' if it is not an AudioWorkletNode and if it has no \'active\' input connections.\nconst setInternalStateToPassiveWhenNecessary = (audioNode, activeInputs) => {\n if (!isAudioWorkletNode(audioNode) && activeInputs.every((connections) => connections.size === 0)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=set-internal-state-to-passive-when-necessary.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-connection-to-audio-node.js\n\n\n\nconst createAddConnectionToAudioNode = (addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode) => {\n const tailTimeTimeoutIds = new WeakMap();\n return (source, destination, output, input, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n const nativeSourceAudioNode = getNativeAudioNode(source);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n addActiveInputConnectionToAudioNode(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n if (isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioNode(activeInputs, source, output, input);\n addPassiveInputConnectionToAudioNode(passiveInputs, input, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n const tailTime = getAudioNodeTailTime(destination);\n if (tailTime === 0) {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }\n else {\n const tailTimeTimeoutId = tailTimeTimeoutIds.get(destination);\n if (tailTimeTimeoutId !== undefined) {\n clearTimeout(tailTimeTimeoutId);\n }\n tailTimeTimeoutIds.set(destination, setTimeout(() => {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }, tailTime * 1000));\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output, input], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output && outputConnection[2] === input, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioNode(activeInputs, source, [output, input, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioNode(passiveInputs, input, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n };\n};\n//# sourceMappingURL=add-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-passive-input-connection-to-audio-node.js\nconst createAddPassiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (passiveInputs, input, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, input, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, input, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input, ignoreDuplicates);\n }\n };\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-silent-connection.js\nconst createAddSilentConnection = (createNativeGainNode) => {\n return (nativeContext, nativeAudioScheduledSourceNode) => {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioScheduledSourceNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnect = () => {\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnect);\n nativeAudioScheduledSourceNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnect);\n };\n};\n//# sourceMappingURL=add-silent-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-unrendered-audio-worklet-node.js\nconst createAddUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).add(audioWorkletNode);\n };\n};\n//# sourceMappingURL=add-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-constructor.js\nconst DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n fftSize: 2048,\n maxDecibels: -30,\n minDecibels: -100,\n smoothingTimeConstant: 0.8\n};\nconst createAnalyserNodeConstructor = (audionNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class AnalyserNode extends audionNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\n const nativeAnalyserNode = createNativeAnalyserNode(nativeContext, mergedOptions);\n const analyserNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createAnalyserNodeRenderer() : null));\n super(context, false, nativeAnalyserNode, analyserNodeRenderer);\n this._nativeAnalyserNode = nativeAnalyserNode;\n }\n get fftSize() {\n return this._nativeAnalyserNode.fftSize;\n }\n set fftSize(value) {\n this._nativeAnalyserNode.fftSize = value;\n }\n get frequencyBinCount() {\n return this._nativeAnalyserNode.frequencyBinCount;\n }\n get maxDecibels() {\n return this._nativeAnalyserNode.maxDecibels;\n }\n set maxDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const maxDecibels = this._nativeAnalyserNode.maxDecibels;\n this._nativeAnalyserNode.maxDecibels = value;\n if (!(value > this._nativeAnalyserNode.minDecibels)) {\n this._nativeAnalyserNode.maxDecibels = maxDecibels;\n throw createIndexSizeError();\n }\n }\n get minDecibels() {\n return this._nativeAnalyserNode.minDecibels;\n }\n set minDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const minDecibels = this._nativeAnalyserNode.minDecibels;\n this._nativeAnalyserNode.minDecibels = value;\n if (!(this._nativeAnalyserNode.maxDecibels > value)) {\n this._nativeAnalyserNode.minDecibels = minDecibels;\n throw createIndexSizeError();\n }\n }\n get smoothingTimeConstant() {\n return this._nativeAnalyserNode.smoothingTimeConstant;\n }\n set smoothingTimeConstant(value) {\n this._nativeAnalyserNode.smoothingTimeConstant = value;\n }\n getByteFrequencyData(array) {\n this._nativeAnalyserNode.getByteFrequencyData(array);\n }\n getByteTimeDomainData(array) {\n this._nativeAnalyserNode.getByteTimeDomainData(array);\n }\n getFloatFrequencyData(array) {\n this._nativeAnalyserNode.getFloatFrequencyData(array);\n }\n getFloatTimeDomainData(array) {\n this._nativeAnalyserNode.getFloatTimeDomainData(array);\n }\n };\n};\n//# sourceMappingURL=analyser-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-owned-by-context.js\nconst isOwnedByContext = (nativeAudioNode, nativeContext) => {\n return nativeAudioNode.context === nativeContext;\n};\n//# sourceMappingURL=is-owned-by-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-renderer-factory.js\n\nconst createAnalyserNodeRendererFactory = (createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAnalyserNodes = new WeakMap();\n const createAnalyserNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAnalyserNode = getNativeAudioNode(proxy);\n // If the initially used nativeAnalyserNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAnalyserNodeIsOwnedByContext = isOwnedByContext(nativeAnalyserNode, nativeOfflineAudioContext);\n if (!nativeAnalyserNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAnalyserNode.channelCount,\n channelCountMode: nativeAnalyserNode.channelCountMode,\n channelInterpretation: nativeAnalyserNode.channelInterpretation,\n fftSize: nativeAnalyserNode.fftSize,\n maxDecibels: nativeAnalyserNode.maxDecibels,\n minDecibels: nativeAnalyserNode.minDecibels,\n smoothingTimeConstant: nativeAnalyserNode.smoothingTimeConstant\n };\n nativeAnalyserNode = createNativeAnalyserNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAnalyserNodes.set(nativeOfflineAudioContext, nativeAnalyserNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAnalyserNode);\n return nativeAnalyserNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAnalyserNode = renderedNativeAnalyserNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAnalyserNode !== undefined) {\n return Promise.resolve(renderedNativeAnalyserNode);\n }\n return createAnalyserNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=analyser-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-copy-channel-methods-out-of-bounds-support.js\nconst testAudioBufferCopyChannelMethodsOutOfBoundsSupport = (nativeAudioBuffer) => {\n try {\n nativeAudioBuffer.copyToChannel(new Float32Array(1), 0, -1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-copy-channel-methods-out-of-bounds-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/index-size-error.js\nconst createIndexSizeError = () => new DOMException(\'\', \'IndexSizeError\');\n//# sourceMappingURL=index-size-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-get-channel-data-method.js\n\nconst wrapAudioBufferGetChannelDataMethod = (audioBuffer) => {\n audioBuffer.getChannelData = ((getChannelData) => {\n return (channel) => {\n try {\n return getChannelData.call(audioBuffer, channel);\n }\n catch (err) {\n if (err.code === 12) {\n throw createIndexSizeError();\n }\n throw err;\n }\n };\n })(audioBuffer.getChannelData);\n};\n//# sourceMappingURL=wrap-audio-buffer-get-channel-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-constructor.js\n\n\nconst audio_buffer_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createAudioBufferConstructor = (audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, testNativeAudioBufferConstructorSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n let nativeOfflineAudioContext = null;\n return class AudioBuffer {\n constructor(options) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...audio_buffer_constructor_DEFAULT_OPTIONS, ...options };\n if (nativeOfflineAudioContext === null) {\n nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n }\n /*\n * Bug #99: Firefox does not throw a NotSupportedError when the numberOfChannels is zero. But it only does it when using the\n * factory function. But since Firefox also supports the constructor everything should be fine.\n */\n const audioBuffer = nativeAudioBufferConstructor !== null &&\n cacheTestResult(testNativeAudioBufferConstructorSupport, testNativeAudioBufferConstructorSupport)\n ? new nativeAudioBufferConstructor({ length, numberOfChannels, sampleRate })\n : nativeOfflineAudioContext.createBuffer(numberOfChannels, length, sampleRate);\n // Bug #99: Safari does not throw an error when the numberOfChannels is zero.\n if (audioBuffer.numberOfChannels === 0) {\n throw createNotSupportedError();\n }\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n /*\n * This does violate all good pratices but it is necessary to allow this AudioBuffer to be used with native\n * (Offline)AudioContexts.\n */\n return audioBuffer;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === AudioBuffer.prototype) ||\n audioBufferStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/constants.js\nconst MOST_NEGATIVE_SINGLE_FLOAT = -3.4028234663852886e38;\nconst MOST_POSITIVE_SINGLE_FLOAT = -MOST_NEGATIVE_SINGLE_FLOAT;\n//# sourceMappingURL=constants.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-active-audio-node.js\n\nconst isActiveAudioNode = (audioNode) => ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n//# sourceMappingURL=is-active-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-constructor.js\n\n\n\n\nconst audio_buffer_source_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n};\nconst createAudioBufferSourceNodeConstructor = (audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class AudioBufferSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...audio_buffer_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const audioBufferSourceNodeRenderer = ((isOffline ? createAudioBufferSourceNodeRenderer() : null));\n super(context, false, nativeAudioBufferSourceNode, audioBufferSourceNodeRenderer);\n this._audioBufferSourceNodeRenderer = audioBufferSourceNodeRenderer;\n this._isBufferNullified = false;\n this._isBufferSet = mergedOptions.buffer !== null;\n this._nativeAudioBufferSourceNode = nativeAudioBufferSourceNode;\n this._onended = null;\n // Bug #73: Safari does not export the correct values for maxValue and minValue.\n this._playbackRate = createAudioParam(this, isOffline, nativeAudioBufferSourceNode.playbackRate, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeAudioBufferSourceNode.buffer;\n }\n set buffer(value) {\n this._nativeAudioBufferSourceNode.buffer = value;\n // Bug #72: Only Chrome & Edge do not allow to reassign the buffer yet.\n if (value !== null) {\n if (this._isBufferSet) {\n throw createInvalidStateError();\n }\n this._isBufferSet = true;\n }\n }\n get loop() {\n return this._nativeAudioBufferSourceNode.loop;\n }\n set loop(value) {\n this._nativeAudioBufferSourceNode.loop = value;\n }\n get loopEnd() {\n return this._nativeAudioBufferSourceNode.loopEnd;\n }\n set loopEnd(value) {\n this._nativeAudioBufferSourceNode.loopEnd = value;\n }\n get loopStart() {\n return this._nativeAudioBufferSourceNode.loopStart;\n }\n set loopStart(value) {\n this._nativeAudioBufferSourceNode.loopStart = value;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioBufferSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeAudioBufferSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get playbackRate() {\n return this._playbackRate;\n }\n start(when = 0, offset = 0, duration) {\n this._nativeAudioBufferSourceNode.start(when, offset, duration);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.start = duration === undefined ? [when, offset] : [when, offset, duration];\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeAudioBufferSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeAudioBufferSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeAudioBufferSourceNode.stop(when);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-renderer-factory.js\n\nconst createAudioBufferSourceNodeRendererFactory = (connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioBufferSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createAudioBufferSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeAudioBufferSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeAudioBufferSourceNodeIsOwnedByContext = isOwnedByContext(nativeAudioBufferSourceNode, nativeOfflineAudioContext);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n const options = {\n buffer: nativeAudioBufferSourceNode.buffer,\n channelCount: nativeAudioBufferSourceNode.channelCount,\n channelCountMode: nativeAudioBufferSourceNode.channelCountMode,\n channelInterpretation: nativeAudioBufferSourceNode.channelInterpretation,\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: nativeAudioBufferSourceNode.loop,\n loopEnd: nativeAudioBufferSourceNode.loopEnd,\n loopStart: nativeAudioBufferSourceNode.loopStart,\n playbackRate: nativeAudioBufferSourceNode.playbackRate.value\n };\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeAudioBufferSourceNode.start(...start);\n }\n if (stop !== null) {\n nativeAudioBufferSourceNode.stop(stop);\n }\n }\n renderedNativeAudioBufferSourceNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await renderAutomation(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n else {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await connectAudioParam(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioBufferSourceNode = renderedNativeAudioBufferSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioBufferSourceNode !== undefined) {\n return Promise.resolve(renderedNativeAudioBufferSourceNode);\n }\n return createAudioBufferSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-buffer-source-node.js\nconst isAudioBufferSourceNode = (audioNode) => {\n return \'playbackRate\' in audioNode;\n};\n//# sourceMappingURL=audio-buffer-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/biquad-filter-node.js\nconst isBiquadFilterNode = (audioNode) => {\n return \'frequency\' in audioNode && \'gain\' in audioNode;\n};\n//# sourceMappingURL=biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/constant-source-node.js\nconst isConstantSourceNode = (audioNode) => {\n return \'offset\' in audioNode;\n};\n//# sourceMappingURL=constant-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/gain-node.js\nconst isGainNode = (audioNode) => {\n return !(\'frequency\' in audioNode) && \'gain\' in audioNode;\n};\n//# sourceMappingURL=gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/oscillator-node.js\nconst isOscillatorNode = (audioNode) => {\n return \'detune\' in audioNode && \'frequency\' in audioNode;\n};\n//# sourceMappingURL=oscillator-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/stereo-panner-node.js\nconst isStereoPannerNode = (audioNode) => {\n return \'pan\' in audioNode;\n};\n//# sourceMappingURL=stereo-panner-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-node-connections.js\n\n\nconst getAudioNodeConnections = (audioNode) => {\n return getValueForKey(AUDIO_NODE_CONNECTIONS_STORE, audioNode);\n};\n//# sourceMappingURL=get-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-param-connections.js\n\n\nconst getAudioParamConnections = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_CONNECTIONS_STORE, audioParam);\n};\n//# sourceMappingURL=get-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-active-audio-node-input-connections.js\n\n\n\n\n\n\n\n\n\n\n\nconst deactivateActiveAudioNodeInputConnections = (audioNode, trace) => {\n const { activeInputs } = getAudioNodeConnections(audioNode);\n activeInputs.forEach((connections) => connections.forEach(([source]) => {\n if (!trace.includes(audioNode)) {\n deactivateActiveAudioNodeInputConnections(source, [...trace, audioNode]);\n }\n }));\n const audioParams = isAudioBufferSourceNode(audioNode)\n ? [\n // Bug #149: Safari does not yet support the detune AudioParam.\n audioNode.playbackRate\n ]\n : isAudioWorkletNode(audioNode)\n ? Array.from(audioNode.parameters.values())\n : isBiquadFilterNode(audioNode)\n ? [audioNode.Q, audioNode.detune, audioNode.frequency, audioNode.gain]\n : isConstantSourceNode(audioNode)\n ? [audioNode.offset]\n : isGainNode(audioNode)\n ? [audioNode.gain]\n : isOscillatorNode(audioNode)\n ? [audioNode.detune, audioNode.frequency]\n : isStereoPannerNode(audioNode)\n ? [audioNode.pan]\n : [];\n for (const audioParam of audioParams) {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections !== undefined) {\n audioParamConnections.activeInputs.forEach(([source]) => deactivateActiveAudioNodeInputConnections(source, trace));\n }\n }\n if (isActiveAudioNode(audioNode)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=deactivate-active-audio-node-input-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-audio-graph.js\n\nconst deactivateAudioGraph = (context) => {\n deactivateActiveAudioNodeInputConnections(context.destination, []);\n};\n//# sourceMappingURL=deactivate-audio-graph.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-valid-latency-hint.js\nconst isValidLatencyHint = (latencyHint) => {\n return (latencyHint === undefined ||\n typeof latencyHint === \'number\' ||\n (typeof latencyHint === \'string\' && (latencyHint === \'balanced\' || latencyHint === \'interactive\' || latencyHint === \'playback\')));\n};\n//# sourceMappingURL=is-valid-latency-hint.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-context-constructor.js\n\n\nconst createAudioContextConstructor = (baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor) => {\n return class AudioContext extends baseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n createMediaElementSource(mediaElement) {\n return new mediaElementAudioSourceNodeConstructor(this, { mediaElement });\n }\n createMediaStreamDestination() {\n return new mediaStreamAudioDestinationNodeConstructor(this);\n }\n createMediaStreamSource(mediaStream) {\n return new mediaStreamAudioSourceNodeConstructor(this, { mediaStream });\n }\n createMediaStreamTrackSource(mediaStreamTrack) {\n return new mediaStreamTrackAudioSourceNodeConstructor(this, { mediaStreamTrack });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-constructor.js\nconst createAudioDestinationNodeConstructor = (audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode) => {\n return class AudioDestinationNode extends audioNodeConstructor {\n constructor(context, channelCount) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const nativeAudioDestinationNode = createNativeAudioDestinationNode(nativeContext, channelCount, isOffline);\n const audioDestinationNodeRenderer = ((isOffline ? createAudioDestinationNodeRenderer(renderInputsOfAudioNode) : null));\n super(context, false, nativeAudioDestinationNode, audioDestinationNodeRenderer);\n this._isNodeOfNativeOfflineAudioContext = isOffline;\n this._nativeAudioDestinationNode = nativeAudioDestinationNode;\n }\n get channelCount() {\n return this._nativeAudioDestinationNode.channelCount;\n }\n set channelCount(value) {\n // Bug #52: Chrome, Edge & Safari do not throw an exception at all.\n // Bug #54: Firefox does throw an IndexSizeError.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (value > this._nativeAudioDestinationNode.maxChannelCount) {\n throw createIndexSizeError();\n }\n this._nativeAudioDestinationNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioDestinationNode.channelCountMode;\n }\n set channelCountMode(value) {\n // Bug #53: No browser does throw an exception yet.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n this._nativeAudioDestinationNode.channelCountMode = value;\n }\n get maxChannelCount() {\n return this._nativeAudioDestinationNode.maxChannelCount;\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-renderer-factory.js\nconst createAudioDestinationNodeRenderer = (renderInputsOfAudioNode) => {\n const renderedNativeAudioDestinationNodes = new WeakMap();\n const createAudioDestinationNode = async (proxy, nativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeOfflineAudioContext.destination;\n renderedNativeAudioDestinationNodes.set(nativeOfflineAudioContext, nativeAudioDestinationNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioDestinationNode);\n return nativeAudioDestinationNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioDestinationNode = renderedNativeAudioDestinationNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioDestinationNode !== undefined) {\n return Promise.resolve(renderedNativeAudioDestinationNode);\n }\n return createAudioDestinationNode(proxy, nativeOfflineAudioContext);\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-listener-factory.js\n\nconst createAudioListenerFactory = (createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors) => {\n return (context, nativeContext) => {\n const nativeListener = nativeContext.listener;\n // Bug #117: Only Chrome & Edge support the new interface already.\n const createFakeAudioParams = () => {\n const buffer = new Float32Array(1);\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 9\n });\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n let isScriptProcessorNodeCreated = false;\n let lastOrientation = [0, 0, -1, 0, 1, 0];\n let lastPosition = [0, 0, 0];\n const createScriptProcessorNode = () => {\n if (isScriptProcessorNodeCreated) {\n return;\n }\n isScriptProcessorNodeCreated = true;\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 9, 0);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2),\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n nativeListener.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 6),\n getFirstSample(inputBuffer, buffer, 7),\n getFirstSample(inputBuffer, buffer, 8)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n nativeListener.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n channelMergerNode.connect(scriptProcessorNode);\n };\n const createSetOrientation = (index) => (value) => {\n if (value !== lastOrientation[index]) {\n lastOrientation[index] = value;\n nativeListener.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n };\n const createSetPosition = (index) => (value) => {\n if (value !== lastPosition[index]) {\n lastPosition[index] = value;\n nativeListener.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n };\n const createFakeAudioParam = (input, initialValue, setValue) => {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: initialValue\n });\n constantSourceNode.connect(channelMergerNode, 0, input);\n // @todo This should be stopped when the context is closed.\n constantSourceNode.start();\n Object.defineProperty(constantSourceNode.offset, \'defaultValue\', {\n get() {\n return initialValue;\n }\n });\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and\n * minValue for GainNodes.\n */\n const audioParam = createAudioParam({ context }, isOffline, constantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n overwriteAccessors(audioParam, \'value\', (get) => () => get.call(audioParam), (set) => (value) => {\n try {\n set.call(audioParam, value);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n }\n createScriptProcessorNode();\n if (isOffline) {\n // Bug #117: Using setOrientation() and setPosition() doesn\'t work with an OfflineAudioContext.\n setValue(value);\n }\n });\n audioParam.cancelAndHoldAtTime = ((cancelAndHoldAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelAndHoldAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelAndHoldAtTime);\n audioParam.cancelScheduledValues = ((cancelScheduledValues) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelScheduledValues.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelScheduledValues);\n audioParam.exponentialRampToValueAtTime = ((exponentialRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = exponentialRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.exponentialRampToValueAtTime);\n audioParam.linearRampToValueAtTime = ((linearRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = linearRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.linearRampToValueAtTime);\n audioParam.setTargetAtTime = ((setTargetAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setTargetAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setTargetAtTime);\n audioParam.setValueAtTime = ((setValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueAtTime);\n audioParam.setValueCurveAtTime = ((setValueCurveAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueCurveAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueCurveAtTime);\n return audioParam;\n };\n return {\n forwardX: createFakeAudioParam(0, 0, createSetOrientation(0)),\n forwardY: createFakeAudioParam(1, 0, createSetOrientation(1)),\n forwardZ: createFakeAudioParam(2, -1, createSetOrientation(2)),\n positionX: createFakeAudioParam(6, 0, createSetPosition(0)),\n positionY: createFakeAudioParam(7, 0, createSetPosition(1)),\n positionZ: createFakeAudioParam(8, 0, createSetPosition(2)),\n upX: createFakeAudioParam(3, 0, createSetOrientation(3)),\n upY: createFakeAudioParam(4, 1, createSetOrientation(4)),\n upZ: createFakeAudioParam(5, 0, createSetOrientation(5))\n };\n };\n const { forwardX, forwardY, forwardZ, positionX, positionY, positionZ, upX, upY, upZ } = nativeListener.forwardX === undefined ? createFakeAudioParams() : nativeListener;\n return {\n get forwardX() {\n return forwardX;\n },\n get forwardY() {\n return forwardY;\n },\n get forwardZ() {\n return forwardZ;\n },\n get positionX() {\n return positionX;\n },\n get positionY() {\n return positionY;\n },\n get positionZ() {\n return positionZ;\n },\n get upX() {\n return upX;\n },\n get upY() {\n return upY;\n },\n get upZ() {\n return upZ;\n }\n };\n };\n};\n//# sourceMappingURL=audio-listener-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node.js\nconst isAudioNode = (audioNodeOrAudioParam) => {\n return \'context\' in audioNodeOrAudioParam;\n};\n//# sourceMappingURL=audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node-output-connection.js\n\nconst isAudioNodeOutputConnection = (outputConnection) => {\n return isAudioNode(outputConnection[0]);\n};\n//# sourceMappingURL=audio-node-output-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/insert-element-in-set.js\nconst insertElementInSet = (set, element, predicate, ignoreDuplicates) => {\n for (const lmnt of set) {\n if (predicate(lmnt)) {\n if (ignoreDuplicates) {\n return false;\n }\n throw Error(\'The set contains at least one similar element.\');\n }\n }\n set.add(element);\n return true;\n};\n//# sourceMappingURL=insert-element-in-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-active-input-connection-to-audio-param.js\n\nconst addActiveInputConnectionToAudioParam = (activeInputs, source, [output, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs, [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-passive-input-connection-to-audio-param.js\n\nconst addPassiveInputConnectionToAudioParam = (passiveInputs, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output, ignoreDuplicates);\n }\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node-faker.js\nconst isNativeAudioNodeFaker = (nativeAudioNodeOrNativeAudioNodeFaker) => {\n return \'inputs\' in nativeAudioNodeOrNativeAudioNodeFaker;\n};\n//# sourceMappingURL=native-audio-node-faker.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/connect-native-audio-node-to-native-audio-node.js\n\nconst connectNativeAudioNodeToNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n const fakeNativeDestinationAudioNode = nativeDestinationAudioNode.inputs[input];\n nativeSourceAudioNode.connect(fakeNativeDestinationAudioNode, output, 0);\n return [fakeNativeDestinationAudioNode, output, 0];\n }\n nativeSourceAudioNode.connect(nativeDestinationAudioNode, output, input);\n return [nativeDestinationAudioNode, output, input];\n};\n//# sourceMappingURL=connect-native-audio-node-to-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection.js\nconst deleteActiveInputConnection = (activeInputConnections, source, output) => {\n for (const activeInputConnection of activeInputConnections) {\n if (activeInputConnection[0] === source && activeInputConnection[1] === output) {\n activeInputConnections.delete(activeInputConnection);\n return activeInputConnection;\n }\n }\n return null;\n};\n//# sourceMappingURL=delete-active-input-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection-to-audio-param.js\n\nconst deleteActiveInputConnectionToAudioParam = (activeInputs, source, output) => {\n return pickElementFromSet(activeInputs, (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-event-listeners-of-audio-node.js\n\nconst deleteEventListenerOfAudioNode = (audioNode, eventListener) => {\n const eventListeners = getEventListenersOfAudioNode(audioNode);\n if (!eventListeners.delete(eventListener)) {\n throw new Error(\'Missing the expected event listener.\');\n }\n};\n//# sourceMappingURL=delete-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-param.js\n\n\nconst deletePassiveInputConnectionToAudioParam = (passiveInputs, source, output) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/disconnect-native-audio-node-from-native-audio-node.js\n\nconst disconnectNativeAudioNodeFromNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode.inputs[input], output, 0);\n }\n else {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode, output, input);\n }\n};\n//# sourceMappingURL=disconnect-native-audio-node-from-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-node.js\n\n\nconst getNativeAudioNode = (audioNode) => {\n return getValueForKey(AUDIO_NODE_STORE, audioNode);\n};\n//# sourceMappingURL=get-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-param.js\n\n\nconst getNativeAudioParam = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_STORE, audioParam);\n};\n//# sourceMappingURL=get-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-part-of-a-cycle.js\n\nconst isPartOfACycle = (audioNode) => {\n return CYCLE_COUNTERS.has(audioNode);\n};\n//# sourceMappingURL=is-part-of-a-cycle.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-passive-audio-node.js\n\nconst isPassiveAudioNode = (audioNode) => {\n return !ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n};\n//# sourceMappingURL=is-passive-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-node-disconnect-method-support.js\nconst testAudioNodeDisconnectMethodSupport = (nativeAudioContext, nativeAudioWorkletNodeConstructor) => {\n return new Promise((resolve) => {\n /*\n * This bug existed in Safari up until v14.0.2. Since AudioWorklets were not supported in Safari until v14.1 the presence of the\n * constructor for an AudioWorkletNode can be used here to skip the test.\n */\n if (nativeAudioWorkletNodeConstructor !== null) {\n resolve(true);\n }\n else {\n const analyzer = nativeAudioContext.createScriptProcessor(256, 1, 1); // tslint:disable-line deprecation\n const dummy = nativeAudioContext.createGain();\n // Bug #95: Safari does not play one sample buffers.\n const ones = nativeAudioContext.createBuffer(1, 2, 44100);\n const channelData = ones.getChannelData(0);\n channelData[0] = 1;\n channelData[1] = 1;\n const source = nativeAudioContext.createBufferSource();\n source.buffer = ones;\n source.loop = true;\n source.connect(analyzer).connect(nativeAudioContext.destination);\n source.connect(dummy);\n source.disconnect(dummy);\n // tslint:disable-next-line:deprecation\n analyzer.onaudioprocess = (event) => {\n const chnnlDt = event.inputBuffer.getChannelData(0); // tslint:disable-line deprecation\n if (Array.prototype.some.call(chnnlDt, (sample) => sample === 1)) {\n resolve(true);\n }\n else {\n resolve(false);\n }\n source.stop();\n analyzer.onaudioprocess = null; // tslint:disable-line:deprecation\n source.disconnect(analyzer);\n analyzer.disconnect(nativeAudioContext.destination);\n };\n source.start();\n }\n });\n};\n//# sourceMappingURL=test-audio-node-disconnect-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/visit-each-audio-node-once.js\nconst visitEachAudioNodeOnce = (cycles, visitor) => {\n const counts = new Map();\n for (const cycle of cycles) {\n for (const audioNode of cycle) {\n const count = counts.get(audioNode);\n counts.set(audioNode, count === undefined ? 1 : count + 1);\n }\n }\n counts.forEach((count, audioNode) => visitor(audioNode, count));\n};\n//# sourceMappingURL=visit-each-audio-node-once.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node.js\nconst isNativeAudioNode = (nativeAudioNodeOrAudioParam) => {\n return \'context\' in nativeAudioNodeOrAudioParam;\n};\n//# sourceMappingURL=native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-node-disconnect-method.js\n\nconst wrapAudioNodeDisconnectMethod = (nativeAudioNode) => {\n const connections = new Map();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const returnValue = isNativeAudioNode(destination) ? connect(destination, output, input) : connect(destination, output);\n // Save the new connection only if the calls to connect above didn\'t throw an error.\n const connectionsToDestination = connections.get(destination);\n if (connectionsToDestination === undefined) {\n connections.set(destination, [{ input, output }]);\n }\n else {\n if (connectionsToDestination.every((connection) => connection.input !== input || connection.output !== output)) {\n connectionsToDestination.push({ input, output });\n }\n }\n return returnValue;\n };\n })(nativeAudioNode.connect.bind(nativeAudioNode));\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n disconnect.apply(nativeAudioNode);\n if (destinationOrOutput === undefined) {\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n for (const [destination, connectionsToDestination] of connections) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== destinationOrOutput);\n if (filteredConnections.length === 0) {\n connections.delete(destination);\n }\n else {\n connections.set(destination, filteredConnections);\n }\n }\n }\n else if (connections.has(destinationOrOutput)) {\n if (output === undefined) {\n connections.delete(destinationOrOutput);\n }\n else {\n const connectionsToDestination = connections.get(destinationOrOutput);\n if (connectionsToDestination !== undefined) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== output && (connection.input !== input || input === undefined));\n if (filteredConnections.length === 0) {\n connections.delete(destinationOrOutput);\n }\n else {\n connections.set(destinationOrOutput, filteredConnections);\n }\n }\n }\n }\n for (const [destination, connectionsToDestination] of connections) {\n connectionsToDestination.forEach((connection) => {\n if (isNativeAudioNode(destination)) {\n nativeAudioNode.connect(destination, connection.output, connection.input);\n }\n else {\n nativeAudioNode.connect(destination, connection.output);\n }\n });\n }\n };\n })(nativeAudioNode.disconnect);\n};\n//# sourceMappingURL=wrap-audio-node-disconnect-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-node-constructor.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst addConnectionToAudioParamOfAudioContext = (source, destination, output, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeAudioNode = getNativeAudioNode(source);\n const nativeAudioParam = getNativeAudioParam(destination);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n addActiveInputConnectionToAudioParam(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.connect(nativeAudioParam, output);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioParam(activeInputs, source, output);\n addPassiveInputConnectionToAudioParam(passiveInputs, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioParam(activeInputs, source, [output, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioParam(passiveInputs, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n};\nconst deleteInputConnectionOfAudioNode = (source, destination, output, input) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs[input], source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n return [passiveInputConnection[2], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputConnectionOfAudioParam = (source, destination, output) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs, source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n return [passiveInputConnection[1], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputsOfAudioNode = (source, isOffline, destination, output, input) => {\n const [listener, isActive] = deleteInputConnectionOfAudioNode(source, destination, output, input);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(getNativeAudioNode(source), getNativeAudioNode(destination), output, input);\n }\n }\n if (isActiveAudioNode(destination)) {\n const { activeInputs } = getAudioNodeConnections(destination);\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n};\nconst deleteInputsOfAudioParam = (source, isOffline, destination, output) => {\n const [listener, isActive] = deleteInputConnectionOfAudioParam(source, destination, output);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n getNativeAudioNode(source).disconnect(getNativeAudioParam(destination), output);\n }\n }\n};\nconst deleteAnyConnection = (source, isOffline) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n }\n audioNodeConnectionsOfSource.outputs.clear();\n return destinations;\n};\nconst deleteConnectionAtOutput = (source, isOffline, output) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (outputConnection[1] === output) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n }\n }\n return destinations;\n};\nconst deleteConnectionToDestination = (source, isOffline, destination, output, input) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n return Array.from(audioNodeConnectionsOfSource.outputs)\n .filter((outputConnection) => outputConnection[0] === destination &&\n (output === undefined || outputConnection[1] === output) &&\n (input === undefined || outputConnection[2] === input))\n .map((outputConnection) => {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n return outputConnection[0];\n });\n};\nconst createAudioNodeConstructor = (addAudioNodeConnections, addConnectionToAudioNode, cacheTestResult, createIncrementCycleCounter, createIndexSizeError, createInvalidAccessError, createNotSupportedError, decrementCycleCounter, detectCycles, eventTargetConstructor, getNativeContext, isNativeAudioContext, isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor) => {\n return class AudioNode extends eventTargetConstructor {\n constructor(context, isActive, nativeAudioNode, audioNodeRenderer) {\n super(nativeAudioNode);\n this._context = context;\n this._nativeAudioNode = nativeAudioNode;\n const nativeContext = getNativeContext(context);\n // Bug #12: Safari does not support to disconnect a specific destination.\n if (isNativeAudioContext(nativeContext) &&\n true !==\n cacheTestResult(testAudioNodeDisconnectMethodSupport, () => {\n return testAudioNodeDisconnectMethodSupport(nativeContext, nativeAudioWorkletNodeConstructor);\n })) {\n wrapAudioNodeDisconnectMethod(nativeAudioNode);\n }\n AUDIO_NODE_STORE.set(this, nativeAudioNode);\n EVENT_LISTENERS.set(this, new Set());\n if (context.state !== \'closed\' && isActive) {\n setInternalStateToActive(this);\n }\n addAudioNodeConnections(this, audioNodeRenderer, nativeAudioNode);\n }\n get channelCount() {\n return this._nativeAudioNode.channelCount;\n }\n set channelCount(value) {\n this._nativeAudioNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioNode.channelCountMode;\n }\n set channelCountMode(value) {\n this._nativeAudioNode.channelCountMode = value;\n }\n get channelInterpretation() {\n return this._nativeAudioNode.channelInterpretation;\n }\n set channelInterpretation(value) {\n this._nativeAudioNode.channelInterpretation = value;\n }\n get context() {\n return this._context;\n }\n get numberOfInputs() {\n return this._nativeAudioNode.numberOfInputs;\n }\n get numberOfOutputs() {\n return this._nativeAudioNode.numberOfOutputs;\n }\n // tslint:disable-next-line:invalid-void\n connect(destination, output = 0, input = 0) {\n // Bug #174: Safari does expose a wrong numberOfOutputs for MediaStreamAudioDestinationNodes.\n if (output < 0 || output >= this._nativeAudioNode.numberOfOutputs) {\n throw createIndexSizeError();\n }\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (isNativeAudioNode(destination) || isNativeAudioParam(destination)) {\n throw createInvalidAccessError();\n }\n if (isAudioNode(destination)) {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n try {\n const connection = connectNativeAudioNodeToNativeAudioNode(this._nativeAudioNode, nativeDestinationAudioNode, output, input);\n const isPassive = isPassiveAudioNode(this);\n if (isOffline || isPassive) {\n this._nativeAudioNode.disconnect(...connection);\n }\n if (this.context.state !== \'closed\' && !isPassive && isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n catch (err) {\n // Bug #41: Safari does not throw the correct exception so far.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioNode = addConnectionToAudioNode(this, destination, output, input, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioNode) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n return destination;\n }\n const nativeAudioParam = getNativeAudioParam(destination);\n /*\n * Bug #73, #147 & #153: Safari does not support to connect an input signal to the playbackRate AudioParam of an\n * AudioBufferSourceNode. This can\'t be easily detected and that\'s why the outdated name property is used here to identify\n * Safari. In addition to that the maxValue property is used to only detect the affected versions below v14.0.2.\n */\n if (nativeAudioParam.name === \'playbackRate\' && nativeAudioParam.maxValue === 1024) {\n throw createNotSupportedError();\n }\n try {\n this._nativeAudioNode.connect(nativeAudioParam, output);\n if (isOffline || isPassiveAudioNode(this)) {\n this._nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n catch (err) {\n // Bug #58: Safari doesn\'t throw an InvalidAccessError yet.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioParam = addConnectionToAudioParamOfAudioContext(this, destination, output, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioParam) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n }\n disconnect(destinationOrOutput, output, input) {\n let destinations;\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (destinationOrOutput === undefined) {\n destinations = deleteAnyConnection(this, isOffline);\n }\n else if (typeof destinationOrOutput === \'number\') {\n if (destinationOrOutput < 0 || destinationOrOutput >= this.numberOfOutputs) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionAtOutput(this, isOffline, destinationOrOutput);\n }\n else {\n if (output !== undefined && (output < 0 || output >= this.numberOfOutputs)) {\n throw createIndexSizeError();\n }\n if (isAudioNode(destinationOrOutput) && input !== undefined && (input < 0 || input >= destinationOrOutput.numberOfInputs)) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionToDestination(this, isOffline, destinationOrOutput, output, input);\n if (destinations.length === 0) {\n throw createInvalidAccessError();\n }\n }\n // Bug #164: Only Firefox detects cycles so far.\n for (const destination of destinations) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, decrementCycleCounter);\n }\n }\n };\n};\n//# sourceMappingURL=audio-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-factory.js\n\nconst createAudioParamFactory = (addAudioParamConnections, audioParamAudioNodeStore, audioParamStore, createAudioParamRenderer, createCancelAndHoldAutomationEvent, createCancelScheduledValuesAutomationEvent, createExponentialRampToValueAutomationEvent, createLinearRampToValueAutomationEvent, createSetTargetAutomationEvent, createSetValueAutomationEvent, createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible) => {\n return (audioNode, isAudioParamOfOfflineAudioContext, nativeAudioParam, maxValue = null, minValue = null) => {\n // Bug #196 Only Safari sets the defaultValue to the initial value.\n const defaultValue = nativeAudioParam.value;\n const automationEventList = new bundle.AutomationEventList(defaultValue);\n const audioParamRenderer = isAudioParamOfOfflineAudioContext ? createAudioParamRenderer(automationEventList) : null;\n const audioParam = {\n get defaultValue() {\n return defaultValue;\n },\n get maxValue() {\n return maxValue === null ? nativeAudioParam.maxValue : maxValue;\n },\n get minValue() {\n return minValue === null ? nativeAudioParam.minValue : minValue;\n },\n get value() {\n return nativeAudioParam.value;\n },\n set value(value) {\n nativeAudioParam.value = value;\n // Bug #98: Firefox & Safari do not yet treat the value setter like a call to setValueAtTime().\n audioParam.setValueAtTime(value, audioNode.context.currentTime);\n },\n cancelAndHoldAtTime(cancelTime) {\n // Bug #28: Firefox & Safari do not yet implement cancelAndHoldAtTime().\n if (typeof nativeAudioParam.cancelAndHoldAtTime === \'function\') {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n nativeAudioParam.cancelAndHoldAtTime(cancelTime);\n }\n else {\n const previousLastEvent = Array.from(automationEventList).pop();\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n const currentLastEvent = Array.from(automationEventList).pop();\n nativeAudioParam.cancelScheduledValues(cancelTime);\n if (previousLastEvent !== currentLastEvent && currentLastEvent !== undefined) {\n if (currentLastEvent.type === \'exponentialRampToValue\') {\n nativeAudioParam.exponentialRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'linearRampToValue\') {\n nativeAudioParam.linearRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'setValue\') {\n nativeAudioParam.setValueAtTime(currentLastEvent.value, currentLastEvent.startTime);\n }\n else if (currentLastEvent.type === \'setValueCurve\') {\n nativeAudioParam.setValueCurveAtTime(currentLastEvent.values, currentLastEvent.startTime, currentLastEvent.duration);\n }\n }\n }\n return audioParam;\n },\n cancelScheduledValues(cancelTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelScheduledValuesAutomationEvent(cancelTime));\n nativeAudioParam.cancelScheduledValues(cancelTime);\n return audioParam;\n },\n exponentialRampToValueAtTime(value, endTime) {\n // Bug #45: Safari does not throw an error yet.\n if (value === 0) {\n throw new RangeError();\n }\n // Bug #187: Safari does not throw an error yet.\n if (!Number.isFinite(endTime) || endTime < 0) {\n throw new RangeError();\n }\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #194: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createExponentialRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.exponentialRampToValueAtTime(value, endTime);\n return audioParam;\n },\n linearRampToValueAtTime(value, endTime) {\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #195: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createLinearRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.linearRampToValueAtTime(value, endTime);\n return audioParam;\n },\n setTargetAtTime(target, startTime, timeConstant) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetTargetAutomationEvent(target, startTime, timeConstant));\n nativeAudioParam.setTargetAtTime(target, startTime, timeConstant);\n return audioParam;\n },\n setValueAtTime(value, startTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueAutomationEvent(value, startTime));\n nativeAudioParam.setValueAtTime(value, startTime);\n return audioParam;\n },\n setValueCurveAtTime(values, startTime, duration) {\n // Bug 183: Safari only accepts a Float32Array.\n const convertedValues = values instanceof Float32Array ? values : new Float32Array(values);\n /*\n * Bug #152: Safari does not correctly interpolate the values of the curve.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the\n * existence of the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n const endTime = startTime + duration;\n const sampleRate = audioNode.context.sampleRate;\n const firstSample = Math.ceil(startTime * sampleRate);\n const lastSample = Math.floor(endTime * sampleRate);\n const numberOfInterpolatedValues = lastSample - firstSample;\n const interpolatedValues = new Float32Array(numberOfInterpolatedValues);\n for (let i = 0; i < numberOfInterpolatedValues; i += 1) {\n const theoreticIndex = ((convertedValues.length - 1) / duration) * ((firstSample + i) / sampleRate - startTime);\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n interpolatedValues[i] =\n lowerIndex === upperIndex\n ? convertedValues[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * convertedValues[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * convertedValues[upperIndex];\n }\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(interpolatedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(interpolatedValues, startTime, duration);\n const timeOfLastSample = lastSample / sampleRate;\n if (timeOfLastSample < endTime) {\n setValueAtTimeUntilPossible(audioParam, interpolatedValues[interpolatedValues.length - 1], timeOfLastSample);\n }\n setValueAtTimeUntilPossible(audioParam, convertedValues[convertedValues.length - 1], endTime);\n }\n else {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(convertedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(convertedValues, startTime, duration);\n }\n return audioParam;\n }\n };\n audioParamStore.set(audioParam, nativeAudioParam);\n audioParamAudioNodeStore.set(audioParam, audioNode);\n addAudioParamConnections(audioParam, audioParamRenderer);\n return audioParam;\n };\n};\n//# sourceMappingURL=audio-param-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-renderer.js\nconst createAudioParamRenderer = (automationEventList) => {\n return {\n replay(audioParam) {\n for (const automationEvent of automationEventList) {\n if (automationEvent.type === \'exponentialRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.exponentialRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'linearRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.linearRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'setTarget\') {\n const { startTime, target, timeConstant } = automationEvent;\n audioParam.setTargetAtTime(target, startTime, timeConstant);\n }\n else if (automationEvent.type === \'setValue\') {\n const { startTime, value } = automationEvent;\n audioParam.setValueAtTime(value, startTime);\n }\n else if (automationEvent.type === \'setValueCurve\') {\n const { duration, startTime, values } = automationEvent;\n audioParam.setValueCurveAtTime(values, startTime, duration);\n }\n else {\n throw new Error("Can\'t apply an unknown automation.");\n }\n }\n }\n };\n};\n//# sourceMappingURL=audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/read-only-map.js\nclass ReadOnlyMap {\n constructor(parameters) {\n this._map = new Map(parameters);\n }\n get size() {\n return this._map.size;\n }\n entries() {\n return this._map.entries();\n }\n forEach(callback, thisArg = null) {\n return this._map.forEach((value, key) => callback.call(thisArg, value, key, this));\n }\n get(name) {\n return this._map.get(name);\n }\n has(name) {\n return this._map.has(name);\n }\n keys() {\n return this._map.keys();\n }\n values() {\n return this._map.values();\n }\n}\n//# sourceMappingURL=read-only-map.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-constructor.js\n\n\nconst audio_worklet_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n // Bug #61: The channelCountMode should be \'max\' according to the spec but is set to \'explicit\' to achieve consistent behavior.\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {},\n processorOptions: {}\n};\nconst createAudioWorkletNodeConstructor = (addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener) => {\n return class AudioWorkletNode extends audioNodeConstructor {\n constructor(context, name, options) {\n var _a;\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = sanitizeAudioWorkletNodeOptions({ ...audio_worklet_node_constructor_DEFAULT_OPTIONS, ...options });\n // Bug #191: Safari doesn\'t throw an error if the options aren\'t clonable.\n testAudioWorkletNodeOptionsClonability(mergedOptions);\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n const processorConstructor = nodeNameToProcessorConstructorMap === null || nodeNameToProcessorConstructorMap === void 0 ? void 0 : nodeNameToProcessorConstructorMap.get(name);\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const nativeContextOrBackupOfflineAudioContext = isOffline || nativeContext.state !== \'closed\'\n ? nativeContext\n : (_a = getBackupOfflineAudioContext(nativeContext)) !== null && _a !== void 0 ? _a : nativeContext;\n const nativeAudioWorkletNode = createNativeAudioWorkletNode(nativeContextOrBackupOfflineAudioContext, isOffline ? null : context.baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, mergedOptions);\n const audioWorkletNodeRenderer = ((isOffline ? createAudioWorkletNodeRenderer(name, mergedOptions, processorConstructor) : null));\n /*\n * @todo Add a mechanism to switch an AudioWorkletNode to passive once the process() function of the AudioWorkletProcessor\n * returns false.\n */\n super(context, true, nativeAudioWorkletNode, audioWorkletNodeRenderer);\n const parameters = [];\n nativeAudioWorkletNode.parameters.forEach((nativeAudioParam, nm) => {\n const audioParam = createAudioParam(this, isOffline, nativeAudioParam);\n parameters.push([nm, audioParam]);\n });\n this._nativeAudioWorkletNode = nativeAudioWorkletNode;\n this._onprocessorerror = null;\n this._parameters = new ReadOnlyMap(parameters);\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to\n * the destination.\n */\n if (isOffline) {\n addUnrenderedAudioWorkletNode(nativeContext, this);\n }\n const { activeInputs } = getAudioNodeConnections(this);\n setActiveAudioWorkletNodeInputs(nativeAudioWorkletNode, activeInputs);\n }\n get onprocessorerror() {\n return this._onprocessorerror;\n }\n set onprocessorerror(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioWorkletNode.onprocessorerror = wrappedListener;\n const nativeOnProcessorError = this._nativeAudioWorkletNode.onprocessorerror;\n this._onprocessorerror =\n nativeOnProcessorError !== null && nativeOnProcessorError === wrappedListener\n ? value\n : nativeOnProcessorError;\n }\n get parameters() {\n if (this._parameters === null) {\n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n return this._nativeAudioWorkletNode.parameters;\n }\n return this._parameters;\n }\n get port() {\n return this._nativeAudioWorkletNode.port;\n }\n };\n};\n//# sourceMappingURL=audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-from-channel.js\nfunction copyFromChannel(audioBuffer, \n// @todo There is currently no way to define something like { [ key: number | string ]: Float32Array }\nparent, key, channelNumber, bufferOffset) {\n if (typeof audioBuffer.copyFromChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = new Float32Array(128);\n }\n audioBuffer.copyFromChannel(parent[key], channelNumber, bufferOffset);\n // Bug #5: Safari does not support copyFromChannel().\n }\n else {\n const channelData = audioBuffer.getChannelData(channelNumber);\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = channelData.slice(bufferOffset, bufferOffset + 128);\n }\n else {\n const slicedInput = new Float32Array(channelData.buffer, bufferOffset * Float32Array.BYTES_PER_ELEMENT, 128);\n parent[key].set(slicedInput);\n }\n }\n}\n//# sourceMappingURL=copy-from-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-to-channel.js\nconst copyToChannel = (audioBuffer, parent, key, channelNumber, bufferOffset) => {\n if (typeof audioBuffer.copyToChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.copyToChannel(parent[key], channelNumber, bufferOffset);\n }\n // Bug #5: Safari does not support copyToChannel().\n }\n else {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.getChannelData(channelNumber).set(parent[key], bufferOffset);\n }\n }\n};\n//# sourceMappingURL=copy-to-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-nested-arrays.js\nconst createNestedArrays = (x, y) => {\n const arrays = [];\n for (let i = 0; i < x; i += 1) {\n const array = [];\n const length = typeof y === \'number\' ? y : y[i];\n for (let j = 0; j < length; j += 1) {\n array.push(new Float32Array(128));\n }\n arrays.push(array);\n }\n return arrays;\n};\n//# sourceMappingURL=create-nested-arrays.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-worklet-processor.js\n\n\n\nconst getAudioWorkletProcessor = (nativeOfflineAudioContext, proxy) => {\n const nodeToProcessorMap = getValueForKey(NODE_TO_PROCESSOR_MAPS, nativeOfflineAudioContext);\n const nativeAudioWorkletNode = getNativeAudioNode(proxy);\n return getValueForKey(nodeToProcessorMap, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-renderer-factory.js\n\n\n\n\n\n\nconst processBuffer = async (proxy, renderedBuffer, nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime) => {\n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n const length = renderedBuffer === null ? Math.ceil(proxy.context.length / 128) * 128 : renderedBuffer.length;\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const processedBuffer = numberOfOutputChannels === 0\n ? null\n : nativeOfflineAudioContext.createBuffer(numberOfOutputChannels, length, nativeOfflineAudioContext.sampleRate);\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n const audioNodeConnections = getAudioNodeConnections(proxy);\n const audioWorkletProcessor = await getAudioWorkletProcessor(nativeOfflineAudioContext, proxy);\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = Array.from(proxy.parameters.keys()).reduce((prmtrs, name) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n for (let i = 0; i < length; i += 128) {\n if (options.numberOfInputs > 0 && renderedBuffer !== null) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(renderedBuffer, inputs[j], k, k, i);\n }\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined && renderedBuffer !== null) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(renderedBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n if (audioNodeConnections.activeInputs[index].size === 0) {\n return [];\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(i / nativeOfflineAudioContext.sampleRate, nativeOfflineAudioContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n if (processedBuffer !== null) {\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(processedBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n if (!activeSourceFlag) {\n break;\n }\n }\n catch (error) {\n proxy.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n break;\n }\n }\n return processedBuffer;\n};\nconst createAudioWorkletNodeRendererFactory = (connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (name, options, processorConstructor) => {\n const renderedNativeAudioNodes = new WeakMap();\n let processedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioWorkletNode = getNativeAudioNode(proxy);\n let nativeOutputNodes = null;\n const nativeAudioWorkletNodeIsOwnedByContext = isOwnedByContext(nativeAudioWorkletNode, nativeOfflineAudioContext);\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // Bug #61: Only Chrome, Edge & Firefox have an implementation of the AudioWorkletNode yet.\n if (nativeAudioWorkletNodeConstructor === null) {\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < proxy.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n const outputGainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n });\n outputGainNode.connect = connectMultipleOutputs.bind(null, outputChannelMergerNodes);\n outputGainNode.disconnect = disconnectMultipleOutputs.bind(null, outputChannelMergerNodes);\n nativeOutputNodes = [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode];\n }\n else if (!nativeAudioWorkletNodeIsOwnedByContext) {\n nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeOfflineAudioContext, name);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeOutputNodes === null ? nativeAudioWorkletNode : nativeOutputNodes[2]);\n if (nativeOutputNodes !== null) {\n if (processedBufferPromise === null) {\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n const numberOfInputChannels = proxy.channelCount * proxy.numberOfInputs;\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n const numberOfChannels = numberOfInputChannels + numberOfParameters;\n const renderBuffer = async () => {\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(numberOfChannels, \n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n Math.ceil(proxy.context.length / 128) * 128, nativeOfflineAudioContext.sampleRate);\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = await Promise.all(Array.from(proxy.parameters.values()).map(async (audioParam) => {\n const constantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: audioParam.value\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, constantSourceNode.offset);\n return constantSourceNode;\n }));\n const inputChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n for (const [index, constantSourceNode] of constantSourceNodes.entries()) {\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n }\n inputChannelMergerNode.connect(partialOfflineAudioContext.destination);\n await Promise.all(gainNodes.map((gainNode) => renderInputsOfAudioNode(proxy, partialOfflineAudioContext, gainNode)));\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n };\n processedBufferPromise = processBuffer(proxy, numberOfChannels === 0 ? null : await renderBuffer(), nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime);\n }\n const processedBuffer = await processedBufferPromise;\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode] = nativeOutputNodes;\n if (processedBuffer !== null) {\n audioBufferSourceNode.buffer = processedBuffer;\n audioBufferSourceNode.start(0);\n }\n audioBufferSourceNode.connect(outputChannelSplitterNode);\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < proxy.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n return outputGainNode;\n }\n if (!nativeAudioWorkletNodeIsOwnedByContext) {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await renderAutomation(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n else {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await connectAudioParam(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioWorkletNode);\n return nativeAudioWorkletNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n deleteUnrenderedAudioWorkletNode(nativeOfflineAudioContext, proxy);\n const renderedNativeAudioWorkletNodeOrGainNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioWorkletNodeOrGainNode !== undefined) {\n return Promise.resolve(renderedNativeAudioWorkletNodeOrGainNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-worklet-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/base-audio-context-constructor.js\nconst createBaseAudioContextConstructor = (addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor) => {\n return class BaseAudioContext extends minimalBaseAudioContextConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext, numberOfChannels);\n this._nativeContext = _nativeContext;\n this._audioWorklet =\n addAudioWorkletModule === undefined\n ? undefined\n : {\n addModule: (moduleURL, options) => {\n return addAudioWorkletModule(this, moduleURL, options);\n }\n };\n }\n get audioWorklet() {\n return this._audioWorklet;\n }\n createAnalyser() {\n return new analyserNodeConstructor(this);\n }\n createBiquadFilter() {\n return new biquadFilterNodeConstructor(this);\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return new audioBufferConstructor({ length, numberOfChannels, sampleRate });\n }\n createBufferSource() {\n return new audioBufferSourceNodeConstructor(this);\n }\n createChannelMerger(numberOfInputs = 6) {\n return new channelMergerNodeConstructor(this, { numberOfInputs });\n }\n createChannelSplitter(numberOfOutputs = 6) {\n return new channelSplitterNodeConstructor(this, { numberOfOutputs });\n }\n createConstantSource() {\n return new constantSourceNodeConstructor(this);\n }\n createConvolver() {\n return new convolverNodeConstructor(this);\n }\n createDelay(maxDelayTime = 1) {\n return new delayNodeConstructor(this, { maxDelayTime });\n }\n createDynamicsCompressor() {\n return new dynamicsCompressorNodeConstructor(this);\n }\n createGain() {\n return new gainNodeConstructor(this);\n }\n createIIRFilter(feedforward, feedback) {\n return new iIRFilterNodeConstructor(this, { feedback, feedforward });\n }\n createOscillator() {\n return new oscillatorNodeConstructor(this);\n }\n createPanner() {\n return new pannerNodeConstructor(this);\n }\n createPeriodicWave(real, imag, constraints = { disableNormalization: false }) {\n return new periodicWaveConstructor(this, { ...constraints, imag, real });\n }\n createStereoPanner() {\n return new stereoPannerNodeConstructor(this);\n }\n createWaveShaper() {\n return new waveShaperNodeConstructor(this);\n }\n decodeAudioData(audioData, successCallback, errorCallback) {\n return decodeAudioData(this._nativeContext, audioData).then((audioBuffer) => {\n if (typeof successCallback === \'function\') {\n successCallback(audioBuffer);\n }\n return audioBuffer;\n }, (err) => {\n if (typeof errorCallback === \'function\') {\n errorCallback(err);\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-constructor.js\n\nconst biquad_filter_node_constructor_DEFAULT_OPTIONS = {\n Q: 1,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 350,\n gain: 0,\n type: \'lowpass\'\n};\nconst createBiquadFilterNodeConstructor = (audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class BiquadFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...biquad_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const biquadFilterNodeRenderer = (isOffline ? createBiquadFilterNodeRenderer() : null);\n super(context, false, nativeBiquadFilterNode, biquadFilterNodeRenderer);\n // Bug #80: Safari does not export the correct values for maxValue and minValue.\n this._Q = createAudioParam(this, isOffline, nativeBiquadFilterNode.Q, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // Bug #78: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeBiquadFilterNode.detune, 1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT), -1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT));\n // Bug #77: Firefox & Safari do not export the correct value for minValue.\n this._frequency = createAudioParam(this, isOffline, nativeBiquadFilterNode.frequency, context.sampleRate / 2, 0);\n // Bug #79: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeBiquadFilterNode.gain, 40 * Math.log10(MOST_POSITIVE_SINGLE_FLOAT), MOST_NEGATIVE_SINGLE_FLOAT);\n this._nativeBiquadFilterNode = nativeBiquadFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get gain() {\n return this._gain;\n }\n get Q() {\n return this._Q;\n }\n get type() {\n return this._nativeBiquadFilterNode.type;\n }\n set type(value) {\n this._nativeBiquadFilterNode.type = value;\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n // Bug #189: Safari does throw an InvalidStateError.\n try {\n this._nativeBiquadFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n catch (err) {\n if (err.code === 11) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n // Bug #68: Safari does not throw an error if the parameters differ in their length.\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n }\n };\n};\n//# sourceMappingURL=biquad-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-renderer-factory.js\n\nconst createBiquadFilterNodeRendererFactory = (connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeBiquadFilterNodes = new WeakMap();\n const createBiquadFilterNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeBiquadFilterNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeBiquadFilterNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeBiquadFilterNodeIsOwnedByContext = isOwnedByContext(nativeBiquadFilterNode, nativeOfflineAudioContext);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n const options = {\n Q: nativeBiquadFilterNode.Q.value,\n channelCount: nativeBiquadFilterNode.channelCount,\n channelCountMode: nativeBiquadFilterNode.channelCountMode,\n channelInterpretation: nativeBiquadFilterNode.channelInterpretation,\n detune: nativeBiquadFilterNode.detune.value,\n frequency: nativeBiquadFilterNode.frequency.value,\n gain: nativeBiquadFilterNode.gain.value,\n type: nativeBiquadFilterNode.type\n };\n nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeBiquadFilterNodes.set(nativeOfflineAudioContext, nativeBiquadFilterNode);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeBiquadFilterNode);\n return nativeBiquadFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeBiquadFilterNode = renderedNativeBiquadFilterNodes.get(nativeOfflineAudioContext);\n if (renderedNativeBiquadFilterNode !== undefined) {\n return Promise.resolve(renderedNativeBiquadFilterNode);\n }\n return createBiquadFilterNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=biquad-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/cache-test-result.js\nconst createCacheTestResult = (ongoingTests, testResults) => {\n return (tester, test) => {\n const cachedTestResult = testResults.get(tester);\n if (cachedTestResult !== undefined) {\n return cachedTestResult;\n }\n const ongoingTest = ongoingTests.get(tester);\n if (ongoingTest !== undefined) {\n return ongoingTest;\n }\n try {\n const synchronousTestResult = test();\n if (synchronousTestResult instanceof Promise) {\n ongoingTests.set(tester, synchronousTestResult);\n return synchronousTestResult\n .catch(() => false)\n .then((finalTestResult) => {\n ongoingTests.delete(tester);\n testResults.set(tester, finalTestResult);\n return finalTestResult;\n });\n }\n testResults.set(tester, synchronousTestResult);\n return synchronousTestResult;\n }\n catch {\n testResults.set(tester, false);\n return false;\n }\n };\n};\n//# sourceMappingURL=cache-test-result.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-constructor.js\nconst channel_merger_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n};\nconst createChannelMergerNodeConstructor = (audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class ChannelMergerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...channel_merger_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeChannelMergerNode = createNativeChannelMergerNode(nativeContext, mergedOptions);\n const channelMergerNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelMergerNodeRenderer() : null));\n super(context, false, nativeChannelMergerNode, channelMergerNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-merger-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-renderer-factory.js\n\nconst createChannelMergerNodeRendererFactory = (createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfInputs: nativeAudioNode.numberOfInputs\n };\n nativeAudioNode = createNativeChannelMergerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-merger-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-constructor.js\nconst channel_splitter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 6,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 6\n};\nconst createChannelSplitterNodeConstructor = (audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions) => {\n return class ChannelSplitterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizeChannelSplitterOptions({ ...channel_splitter_node_constructor_DEFAULT_OPTIONS, ...options });\n const nativeChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, mergedOptions);\n const channelSplitterNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelSplitterNodeRenderer() : null));\n super(context, false, nativeChannelSplitterNode, channelSplitterNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-splitter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-renderer-factory.js\n\nconst createChannelSplitterNodeRendererFactory = (createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfOutputs: nativeAudioNode.numberOfOutputs\n };\n nativeAudioNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-splitter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-audio-param.js\nconst createConnectAudioParam = (renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=connect-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-multiple-outputs.js\n\nconst createConnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destination, output = 0, input = 0) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n if (isNativeAudioNode(destination)) {\n return outputAudioNode.connect(destination, 0, input);\n }\n return outputAudioNode.connect(destination, 0);\n };\n};\n//# sourceMappingURL=connect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connected-native-audio-buffer-source-node-factory.js\nconst createConnectedNativeAudioBufferSourceNodeFactory = (createNativeAudioBufferSourceNode) => {\n return (nativeContext, nativeAudioNode) => {\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const nativeAudioBuffer = nativeContext.createBuffer(1, 2, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.loop = true;\n nativeAudioBufferSourceNode.connect(nativeAudioNode);\n nativeAudioBufferSourceNode.start();\n return () => {\n nativeAudioBufferSourceNode.stop();\n nativeAudioBufferSourceNode.disconnect(nativeAudioNode);\n };\n };\n};\n//# sourceMappingURL=connected-native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-constructor.js\n\n\n\n\nconst constant_source_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n offset: 1\n};\nconst createConstantSourceNodeConstructor = (audioNodeConstructor, createAudioParam, createConstantSourceNodeRendererFactory, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class ConstantSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...constant_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConstantSourceNode = createNativeConstantSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const constantSourceNodeRenderer = ((isOffline ? createConstantSourceNodeRendererFactory() : null));\n super(context, false, nativeConstantSourceNode, constantSourceNodeRenderer);\n this._constantSourceNodeRenderer = constantSourceNodeRenderer;\n this._nativeConstantSourceNode = nativeConstantSourceNode;\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and minValue\n * for GainNodes.\n */\n this._offset = createAudioParam(this, isOffline, nativeConstantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._onended = null;\n }\n get offset() {\n return this._offset;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeConstantSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeConstantSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n start(when = 0) {\n this._nativeConstantSourceNode.start(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeConstantSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeConstantSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeConstantSourceNode.stop(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=constant-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-renderer-factory.js\n\nconst createConstantSourceNodeRendererFactory = (connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConstantSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createConstantSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConstantSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeConstantSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeConstantSourceNodeIsOwnedByContext = isOwnedByContext(nativeConstantSourceNode, nativeOfflineAudioContext);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeConstantSourceNode.channelCount,\n channelCountMode: nativeConstantSourceNode.channelCountMode,\n channelInterpretation: nativeConstantSourceNode.channelInterpretation,\n offset: nativeConstantSourceNode.offset.value\n };\n nativeConstantSourceNode = createNativeConstantSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeConstantSourceNode.start(start);\n }\n if (stop !== null) {\n nativeConstantSourceNode.stop(stop);\n }\n }\n renderedNativeConstantSourceNodes.set(nativeOfflineAudioContext, nativeConstantSourceNode);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConstantSourceNode = renderedNativeConstantSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConstantSourceNode !== undefined) {\n return Promise.resolve(renderedNativeConstantSourceNode);\n }\n return createConstantSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=constant-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convert-number-to-unsigned-long.js\nconst createConvertNumberToUnsignedLong = (unit32Array) => {\n return (value) => {\n unit32Array[0] = value;\n return unit32Array[0];\n };\n};\n//# sourceMappingURL=convert-number-to-unsigned-long.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-constructor.js\nconst convolver_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n disableNormalization: false\n};\nconst createConvolverNodeConstructor = (audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class ConvolverNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...convolver_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConvolverNode = createNativeConvolverNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const convolverNodeRenderer = (isOffline ? createConvolverNodeRenderer() : null);\n super(context, false, nativeConvolverNode, convolverNodeRenderer);\n this._isBufferNullified = false;\n this._nativeConvolverNode = nativeConvolverNode;\n if (mergedOptions.buffer !== null) {\n setAudioNodeTailTime(this, mergedOptions.buffer.duration);\n }\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeConvolverNode.buffer;\n }\n set buffer(value) {\n this._nativeConvolverNode.buffer = value;\n // Bug #115: Safari does not allow to set the buffer to null.\n if (value === null && this._nativeConvolverNode.buffer !== null) {\n const nativeContext = this._nativeConvolverNode.context;\n this._nativeConvolverNode.buffer = nativeContext.createBuffer(1, 1, nativeContext.sampleRate);\n this._isBufferNullified = true;\n setAudioNodeTailTime(this, 0);\n }\n else {\n this._isBufferNullified = false;\n setAudioNodeTailTime(this, this._nativeConvolverNode.buffer === null ? 0 : this._nativeConvolverNode.buffer.duration);\n }\n }\n get normalize() {\n return this._nativeConvolverNode.normalize;\n }\n set normalize(value) {\n this._nativeConvolverNode.normalize = value;\n }\n };\n};\n//# sourceMappingURL=convolver-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-renderer-factory.js\n\n\nconst createConvolverNodeRendererFactory = (createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConvolverNodes = new WeakMap();\n const createConvolverNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConvolverNode = getNativeAudioNode(proxy);\n // If the initially used nativeConvolverNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeConvolverNodeIsOwnedByContext = isOwnedByContext(nativeConvolverNode, nativeOfflineAudioContext);\n if (!nativeConvolverNodeIsOwnedByContext) {\n const options = {\n buffer: nativeConvolverNode.buffer,\n channelCount: nativeConvolverNode.channelCount,\n channelCountMode: nativeConvolverNode.channelCountMode,\n channelInterpretation: nativeConvolverNode.channelInterpretation,\n disableNormalization: !nativeConvolverNode.normalize\n };\n nativeConvolverNode = createNativeConvolverNode(nativeOfflineAudioContext, options);\n }\n renderedNativeConvolverNodes.set(nativeOfflineAudioContext, nativeConvolverNode);\n if (isNativeAudioNodeFaker(nativeConvolverNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode);\n }\n return nativeConvolverNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConvolverNode = renderedNativeConvolverNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConvolverNode !== undefined) {\n return Promise.resolve(renderedNativeConvolverNode);\n }\n return createConvolverNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=convolver-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/create-native-offline-audio-context.js\nconst createCreateNativeOfflineAudioContext = (createNotSupportedError, nativeOfflineAudioContextConstructor) => {\n return (numberOfChannels, length, sampleRate) => {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n try {\n return new nativeOfflineAudioContextConstructor(numberOfChannels, length, sampleRate);\n }\n catch (err) {\n // Bug #143, #144 & #146: Safari throws a SyntaxError when numberOfChannels, length or sampleRate are invalid.\n if (err.name === \'SyntaxError\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n };\n};\n//# sourceMappingURL=create-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/data-clone-error.js\nconst createDataCloneError = () => new DOMException(\'\', \'DataCloneError\');\n//# sourceMappingURL=data-clone-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/detach-array-buffer.js\nconst detachArrayBuffer = (arrayBuffer) => {\n const { port1, port2 } = new MessageChannel();\n return new Promise((resolve) => {\n const closeAndResolve = () => {\n port2.onmessage = null;\n port1.close();\n port2.close();\n resolve();\n };\n port2.onmessage = () => closeAndResolve();\n try {\n port1.postMessage(arrayBuffer, [arrayBuffer]);\n }\n catch {\n // Ignore errors.\n }\n finally {\n closeAndResolve();\n }\n });\n};\n//# sourceMappingURL=detach-array-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decode-audio-data.js\n\n\nconst createDecodeAudioData = (audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, detachedArrayBuffers, getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (anyContext, audioData) => {\n const nativeContext = isNativeContext(anyContext) ? anyContext : getNativeContext(anyContext);\n // Bug #43: Only Chrome and Edge do throw a DataCloneError.\n if (detachedArrayBuffers.has(audioData)) {\n const err = createDataCloneError();\n return Promise.reject(err);\n }\n // The audioData parameter maybe of a type which can\'t be added to a WeakSet.\n try {\n detachedArrayBuffers.add(audioData);\n }\n catch {\n // Ignore errors.\n }\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeContext))) {\n return nativeContext.decodeAudioData(audioData).then((audioBuffer) => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n detachArrayBuffer(audioData).catch(() => {\n // Ignore errors.\n });\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n }\n // Bug #21: Safari does not return a Promise yet.\n return new Promise((resolve, reject) => {\n const complete = async () => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n try {\n await detachArrayBuffer(audioData);\n }\n catch {\n // Ignore errors.\n }\n };\n const fail = (err) => {\n reject(err);\n complete();\n };\n // Bug #26: Safari throws a synchronous error.\n try {\n // Bug #1: Safari requires a successCallback.\n nativeContext.decodeAudioData(audioData, (audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n complete().then(() => resolve(audioBuffer));\n }, (err) => {\n // Bug #4: Safari returns null instead of an error.\n if (err === null) {\n fail(createEncodingError());\n }\n else {\n fail(err);\n }\n });\n }\n catch (err) {\n fail(err);\n }\n });\n };\n};\n//# sourceMappingURL=decode-audio-data.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decrement-cycle-counter.js\n\nconst createDecrementCycleCounter = (connectNativeAudioNodeToNativeAudioNode, cycleCounters, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n throw new Error(\'Missing the expected cycle count.\');\n }\n const nativeContext = getNativeContext(audioNode.context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (cycleCounter === count) {\n cycleCounters.delete(audioNode);\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.connect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n }\n else {\n cycleCounters.set(audioNode, cycleCounter - count);\n }\n };\n};\n//# sourceMappingURL=decrement-cycle-counter.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-constructor.js\nconst delay_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n delayTime: 0,\n maxDelayTime: 1\n};\nconst createDelayNodeConstructor = (audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DelayNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...delay_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDelayNode = createNativeDelayNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const delayNodeRenderer = (isOffline ? createDelayNodeRenderer(mergedOptions.maxDelayTime) : null);\n super(context, false, nativeDelayNode, delayNodeRenderer);\n this._delayTime = createAudioParam(this, isOffline, nativeDelayNode.delayTime);\n setAudioNodeTailTime(this, mergedOptions.maxDelayTime);\n }\n get delayTime() {\n return this._delayTime;\n }\n };\n};\n//# sourceMappingURL=delay-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-renderer-factory.js\n\nconst createDelayNodeRendererFactory = (connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return (maxDelayTime) => {\n const renderedNativeDelayNodes = new WeakMap();\n const createDelayNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDelayNode = getNativeAudioNode(proxy);\n // If the initially used nativeDelayNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeDelayNodeIsOwnedByContext = isOwnedByContext(nativeDelayNode, nativeOfflineAudioContext);\n if (!nativeDelayNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeDelayNode.channelCount,\n channelCountMode: nativeDelayNode.channelCountMode,\n channelInterpretation: nativeDelayNode.channelInterpretation,\n delayTime: nativeDelayNode.delayTime.value,\n maxDelayTime\n };\n nativeDelayNode = createNativeDelayNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDelayNodes.set(nativeOfflineAudioContext, nativeDelayNode);\n if (!nativeDelayNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDelayNode);\n return nativeDelayNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDelayNode = renderedNativeDelayNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDelayNode !== undefined) {\n return Promise.resolve(renderedNativeDelayNode);\n }\n return createDelayNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=delay-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-active-input-connection-to-audio-node.js\nconst createDeleteActiveInputConnectionToAudioNode = (pickElementFromSet) => {\n return (activeInputs, source, output, input) => {\n return pickElementFromSet(activeInputs[input], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n };\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-unrendered-audio-worklet-node.js\nconst createDeleteUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).delete(audioWorkletNode);\n };\n};\n//# sourceMappingURL=delete-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/delay-node.js\nconst isDelayNode = (audioNode) => {\n return \'delayTime\' in audioNode;\n};\n//# sourceMappingURL=delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/detect-cycles.js\n\n\nconst createDetectCycles = (audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey) => {\n return function detectCycles(chain, nextLink) {\n const audioNode = isAudioNode(nextLink) ? nextLink : getValueForKey(audioParamAudioNodeStore, nextLink);\n if (isDelayNode(audioNode)) {\n return [];\n }\n if (chain[0] === audioNode) {\n return [chain];\n }\n if (chain.includes(audioNode)) {\n return [];\n }\n const { outputs } = getAudioNodeConnections(audioNode);\n return Array.from(outputs)\n .map((outputConnection) => detectCycles([...chain, audioNode], outputConnection[0]))\n .reduce((mergedCycles, nestedCycles) => mergedCycles.concat(nestedCycles), []);\n };\n};\n//# sourceMappingURL=detect-cycles.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/disconnect-multiple-outputs.js\n\nconst getOutputAudioNodeAtIndex = (createIndexSizeError, outputAudioNodes, output) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n return outputAudioNode;\n};\nconst createDisconnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destinationOrOutput = undefined, output = undefined, input = 0) => {\n if (destinationOrOutput === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect());\n }\n if (typeof destinationOrOutput === \'number\') {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, destinationOrOutput).disconnect();\n }\n if (isNativeAudioNode(destinationOrOutput)) {\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n if (input === undefined) {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0, input);\n }\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n };\n};\n//# sourceMappingURL=disconnect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-constructor.js\nconst dynamics_compressor_node_constructor_DEFAULT_OPTIONS = {\n attack: 0.003,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24\n};\nconst createDynamicsCompressorNodeConstructor = (audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DynamicsCompressorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...dynamics_compressor_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const dynamicsCompressorNodeRenderer = (isOffline ? createDynamicsCompressorNodeRenderer() : null);\n super(context, false, nativeDynamicsCompressorNode, dynamicsCompressorNodeRenderer);\n this._attack = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.attack);\n this._knee = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.knee);\n this._nativeDynamicsCompressorNode = nativeDynamicsCompressorNode;\n this._ratio = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.ratio);\n this._release = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.release);\n this._threshold = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.threshold);\n setAudioNodeTailTime(this, 0.006);\n }\n get attack() {\n return this._attack;\n }\n // Bug #108: Safari allows a channelCount of three and above which is why the getter and setter needs to be overwritten here.\n get channelCount() {\n return this._nativeDynamicsCompressorNode.channelCount;\n }\n set channelCount(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCount;\n this._nativeDynamicsCompressorNode.channelCount = value;\n if (value > 2) {\n this._nativeDynamicsCompressorNode.channelCount = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n /*\n * Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\' yet which is why the getter and setter needs to be\n * overwritten here.\n */\n get channelCountMode() {\n return this._nativeDynamicsCompressorNode.channelCountMode;\n }\n set channelCountMode(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCountMode;\n this._nativeDynamicsCompressorNode.channelCountMode = value;\n if (value === \'max\') {\n this._nativeDynamicsCompressorNode.channelCountMode = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n get knee() {\n return this._knee;\n }\n get ratio() {\n return this._ratio;\n }\n get reduction() {\n // Bug #111: Safari returns an AudioParam instead of a number.\n if (typeof this._nativeDynamicsCompressorNode.reduction.value === \'number\') {\n return this._nativeDynamicsCompressorNode.reduction.value;\n }\n return this._nativeDynamicsCompressorNode.reduction;\n }\n get release() {\n return this._release;\n }\n get threshold() {\n return this._threshold;\n }\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-renderer-factory.js\n\nconst createDynamicsCompressorNodeRendererFactory = (connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeDynamicsCompressorNodes = new WeakMap();\n const createDynamicsCompressorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDynamicsCompressorNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeDynamicsCompressorNode was not constructed on the same OfflineAudioContext it needs to be\n * created again.\n */\n const nativeDynamicsCompressorNodeIsOwnedByContext = isOwnedByContext(nativeDynamicsCompressorNode, nativeOfflineAudioContext);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n const options = {\n attack: nativeDynamicsCompressorNode.attack.value,\n channelCount: nativeDynamicsCompressorNode.channelCount,\n channelCountMode: nativeDynamicsCompressorNode.channelCountMode,\n channelInterpretation: nativeDynamicsCompressorNode.channelInterpretation,\n knee: nativeDynamicsCompressorNode.knee.value,\n ratio: nativeDynamicsCompressorNode.ratio.value,\n release: nativeDynamicsCompressorNode.release.value,\n threshold: nativeDynamicsCompressorNode.threshold.value\n };\n nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDynamicsCompressorNodes.set(nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await renderAutomation(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await renderAutomation(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await renderAutomation(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await renderAutomation(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await connectAudioParam(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await connectAudioParam(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await connectAudioParam(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await connectAudioParam(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n return nativeDynamicsCompressorNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDynamicsCompressorNode = renderedNativeDynamicsCompressorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDynamicsCompressorNode !== undefined) {\n return Promise.resolve(renderedNativeDynamicsCompressorNode);\n }\n return createDynamicsCompressorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/encoding-error.js\nconst createEncodingError = () => new DOMException(\'\', \'EncodingError\');\n//# sourceMappingURL=encoding-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/evaluate-source.js\nconst createEvaluateSource = (window) => {\n return (source) => new Promise((resolve, reject) => {\n if (window === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n return;\n }\n const head = window.document.head;\n if (head === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n }\n else {\n const script = window.document.createElement(\'script\');\n // @todo Safari doesn\'t like URLs with a type of \'application/javascript; charset=utf-8\'.\n const blob = new Blob([source], { type: \'application/javascript\' });\n const url = URL.createObjectURL(blob);\n const originalOnErrorHandler = window.onerror;\n const removeErrorEventListenerAndRevokeUrl = () => {\n window.onerror = originalOnErrorHandler;\n URL.revokeObjectURL(url);\n };\n window.onerror = (message, src, lineno, colno, error) => {\n // @todo Edge thinks the source is the one of the html document.\n if (src === url || (src === window.location.href && lineno === 1 && colno === 1)) {\n removeErrorEventListenerAndRevokeUrl();\n reject(error);\n return false;\n }\n if (originalOnErrorHandler !== null) {\n return originalOnErrorHandler(message, src, lineno, colno, error);\n }\n };\n script.onerror = () => {\n removeErrorEventListenerAndRevokeUrl();\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n };\n script.onload = () => {\n removeErrorEventListenerAndRevokeUrl();\n resolve();\n };\n script.src = url;\n script.type = \'module\';\n head.appendChild(script);\n }\n });\n};\n//# sourceMappingURL=evaluate-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/event-target-constructor.js\nconst createEventTargetConstructor = (wrapEventListener) => {\n return class EventTarget {\n constructor(_nativeEventTarget) {\n this._nativeEventTarget = _nativeEventTarget;\n this._listeners = new WeakMap();\n }\n addEventListener(type, listener, options) {\n if (listener !== null) {\n let wrappedEventListener = this._listeners.get(listener);\n if (wrappedEventListener === undefined) {\n wrappedEventListener = wrapEventListener(this, listener);\n if (typeof listener === \'function\') {\n this._listeners.set(listener, wrappedEventListener);\n }\n }\n this._nativeEventTarget.addEventListener(type, wrappedEventListener, options);\n }\n }\n dispatchEvent(event) {\n return this._nativeEventTarget.dispatchEvent(event);\n }\n removeEventListener(type, listener, options) {\n const wrappedEventListener = listener === null ? undefined : this._listeners.get(listener);\n this._nativeEventTarget.removeEventListener(type, wrappedEventListener === undefined ? null : wrappedEventListener, options);\n }\n };\n};\n//# sourceMappingURL=event-target-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/expose-current-frame-and-current-time.js\nconst createExposeCurrentFrameAndCurrentTime = (window) => {\n return (currentTime, sampleRate, fn) => {\n Object.defineProperties(window, {\n currentFrame: {\n configurable: true,\n get() {\n return Math.round(currentTime * sampleRate);\n }\n },\n currentTime: {\n configurable: true,\n get() {\n return currentTime;\n }\n }\n });\n try {\n return fn();\n }\n finally {\n if (window !== null) {\n delete window.currentFrame;\n delete window.currentTime;\n }\n }\n };\n};\n//# sourceMappingURL=expose-current-frame-and-current-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/fetch-source.js\nconst createFetchSource = (createAbortError) => {\n return async (url) => {\n try {\n const response = await fetch(url);\n if (response.ok) {\n return [await response.text(), response.url];\n }\n }\n catch {\n // Ignore errors.\n } // tslint:disable-line:no-empty\n throw createAbortError();\n };\n};\n//# sourceMappingURL=fetch-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-constructor.js\n\nconst gain_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n gain: 1\n};\nconst createGainNodeConstructor = (audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class GainNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...gain_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeGainNode = createNativeGainNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const gainNodeRenderer = (isOffline ? createGainNodeRenderer() : null);\n super(context, false, nativeGainNode, gainNodeRenderer);\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeGainNode.gain, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get gain() {\n return this._gain;\n }\n };\n};\n//# sourceMappingURL=gain-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-renderer-factory.js\n\nconst createGainNodeRendererFactory = (connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeGainNodes = new WeakMap();\n const createGainNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = getNativeAudioNode(proxy);\n // If the initially used nativeGainNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeGainNodeIsOwnedByContext = isOwnedByContext(nativeGainNode, nativeOfflineAudioContext);\n if (!nativeGainNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeGainNode.channelCount,\n channelCountMode: nativeGainNode.channelCountMode,\n channelInterpretation: nativeGainNode.channelInterpretation,\n gain: nativeGainNode.gain.value\n };\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, options);\n }\n renderedNativeGainNodes.set(nativeOfflineAudioContext, nativeGainNode);\n if (!nativeGainNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeGainNode);\n return nativeGainNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNode = renderedNativeGainNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNode !== undefined) {\n return Promise.resolve(renderedNativeGainNode);\n }\n return createGainNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=gain-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-active-audio-worklet-node-inputs.js\nconst createGetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore, getValueForKey) => {\n return (nativeAudioWorkletNode) => getValueForKey(activeAudioWorkletNodeInputsStore, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-renderer.js\nconst createGetAudioNodeRenderer = (getAudioNodeConnections) => {\n return (audioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n if (audioNodeConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioNode in the audio graph.\');\n }\n return audioNodeConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-node-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-tail-time.js\nconst createGetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode) => { var _a; return (_a = audioNodeTailTimeStore.get(audioNode)) !== null && _a !== void 0 ? _a : 0; };\n};\n//# sourceMappingURL=get-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-param-renderer.js\nconst createGetAudioParamRenderer = (getAudioParamConnections) => {\n return (audioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioParam in the audio graph.\');\n }\n return audioParamConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-backup-offline-audio-context.js\nconst createGetBackupOfflineAudioContext = (backupOfflineAudioContextStore) => {\n return (nativeContext) => {\n return backupOfflineAudioContextStore.get(nativeContext);\n };\n};\n//# sourceMappingURL=get-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-state-error.js\nconst createInvalidStateError = () => new DOMException(\'\', \'InvalidStateError\');\n//# sourceMappingURL=invalid-state-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-native-context.js\n\nconst createGetNativeContext = (contextStore) => {\n return (context) => {\n const nativeContext = contextStore.get(context);\n if (nativeContext === undefined) {\n throw createInvalidStateError();\n }\n return (nativeContext);\n };\n};\n//# sourceMappingURL=get-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-or-create-backup-offline-audio-context.js\nconst createGetOrCreateBackupOfflineAudioContext = (backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor) => {\n return (nativeContext) => {\n let backupOfflineAudioContext = backupOfflineAudioContextStore.get(nativeContext);\n if (backupOfflineAudioContext !== undefined) {\n return backupOfflineAudioContext;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n backupOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n backupOfflineAudioContextStore.set(nativeContext, backupOfflineAudioContext);\n return backupOfflineAudioContext;\n };\n};\n//# sourceMappingURL=get-or-create-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-unrendered-audio-worklet-nodes.js\nconst createGetUnrenderedAudioWorkletNodes = (unrenderedAudioWorkletNodeStore) => {\n return (nativeContext) => {\n const unrenderedAudioWorkletNodes = unrenderedAudioWorkletNodeStore.get(nativeContext);\n if (unrenderedAudioWorkletNodes === undefined) {\n throw new Error(\'The context has no set of AudioWorkletNodes.\');\n }\n return unrenderedAudioWorkletNodes;\n };\n};\n//# sourceMappingURL=get-unrendered-audio-worklet-nodes.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-access-error.js\nconst createInvalidAccessError = () => new DOMException(\'\', \'InvalidAccessError\');\n//# sourceMappingURL=invalid-access-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-iir-filter-node-get-frequency-response-method.js\n\nconst wrapIIRFilterNodeGetFrequencyResponseMethod = (nativeIIRFilterNode) => {\n nativeIIRFilterNode.getFrequencyResponse = ((getFrequencyResponse) => {\n return (frequencyHz, magResponse, phaseResponse) => {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n return getFrequencyResponse.call(nativeIIRFilterNode, frequencyHz, magResponse, phaseResponse);\n };\n })(nativeIIRFilterNode.getFrequencyResponse);\n};\n//# sourceMappingURL=wrap-iir-filter-node-get-frequency-response-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-constructor.js\n\nconst iir_filter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\'\n};\nconst createIIRFilterNodeConstructor = (audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class IIRFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = { ...iir_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeIIRFilterNode = createNativeIIRFilterNode(nativeContext, isOffline ? null : context.baseLatency, mergedOptions);\n const iirFilterNodeRenderer = ((isOffline ? createIIRFilterNodeRenderer(mergedOptions.feedback, mergedOptions.feedforward) : null));\n super(context, false, nativeIIRFilterNode, iirFilterNodeRenderer);\n // Bug #23 & #24: FirefoxDeveloper does not throw an InvalidAccessError.\n // @todo Write a test which allows other browsers to remain unpatched.\n wrapIIRFilterNodeGetFrequencyResponseMethod(nativeIIRFilterNode);\n this._nativeIIRFilterNode = nativeIIRFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n return this._nativeIIRFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n };\n};\n//# sourceMappingURL=iir-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/filter-buffer.js\n// This implementation as shamelessly inspired by source code of\n// tslint:disable-next-line:max-line-length\n// {@link https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/audio/IIRFilter.cpp|Chromium\'s IIRFilter}.\nconst filterBuffer = (feedback, feedbackLength, feedforward, feedforwardLength, minLength, xBuffer, yBuffer, bufferIndex, bufferLength, input, output) => {\n const inputLength = input.length;\n let i = bufferIndex;\n for (let j = 0; j < inputLength; j += 1) {\n let y = feedforward[0] * input[j];\n for (let k = 1; k < minLength; k += 1) {\n const x = (i - k) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n y += feedforward[k] * xBuffer[x];\n y -= feedback[k] * yBuffer[x];\n }\n for (let k = minLength; k < feedforwardLength; k += 1) {\n y += feedforward[k] * xBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n for (let k = minLength; k < feedbackLength; k += 1) {\n y -= feedback[k] * yBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n xBuffer[i] = input[j];\n yBuffer[i] = y;\n i = (i + 1) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n output[j] = y;\n }\n return i;\n};\n//# sourceMappingURL=filter-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-renderer-factory.js\n\n\nconst filterFullBuffer = (renderedBuffer, nativeOfflineAudioContext, feedback, feedforward) => {\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedbackLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedforwardLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const bufferLength = 32;\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n const filteredBuffer = nativeOfflineAudioContext.createBuffer(renderedBuffer.numberOfChannels, renderedBuffer.length, renderedBuffer.sampleRate);\n const numberOfChannels = renderedBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = renderedBuffer.getChannelData(i);\n const output = filteredBuffer.getChannelData(i);\n xBuffer.fill(0);\n yBuffer.fill(0);\n filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffer, yBuffer, 0, bufferLength, input, output);\n }\n return filteredBuffer;\n};\nconst createIIRFilterNodeRendererFactory = (createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (feedback, feedforward) => {\n const renderedNativeAudioNodes = new WeakMap();\n let filteredBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = null;\n let nativeIIRFilterNode = getNativeAudioNode(proxy);\n // If the initially used nativeIIRFilterNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeIIRFilterNodeIsOwnedByContext = isOwnedByContext(nativeIIRFilterNode, nativeOfflineAudioContext);\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeOfflineAudioContext.createIIRFilter === undefined) {\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n }\n else if (!nativeIIRFilterNodeIsOwnedByContext) {\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n nativeIIRFilterNode = nativeOfflineAudioContext.createIIRFilter(feedforward, feedback);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode === null ? nativeIIRFilterNode : nativeAudioBufferSourceNode);\n if (nativeAudioBufferSourceNode !== null) {\n if (filteredBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n proxy.context.destination.channelCount, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n filteredBufferPromise = (async () => {\n await renderInputsOfAudioNode(proxy, partialOfflineAudioContext, partialOfflineAudioContext.destination);\n const renderedBuffer = await renderNativeOfflineAudioContext(partialOfflineAudioContext);\n return filterFullBuffer(renderedBuffer, nativeOfflineAudioContext, feedback, feedforward);\n })();\n }\n const filteredBuffer = await filteredBufferPromise;\n nativeAudioBufferSourceNode.buffer = filteredBuffer;\n nativeAudioBufferSourceNode.start(0);\n return nativeAudioBufferSourceNode;\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeIIRFilterNode);\n return nativeIIRFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=iir-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/increment-cycle-counter-factory.js\n\nconst createIncrementCycleCounterFactory = (cycleCounters, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode) => {\n return (isOffline) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.disconnect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n cycleCounters.set(audioNode, count);\n }\n else {\n cycleCounters.set(audioNode, cycleCounter + count);\n }\n };\n };\n};\n//# sourceMappingURL=increment-cycle-counter-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-context.js\nconst createIsAnyAudioContext = (contextStore, isNativeAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeAudioContext(nativeContext) || isNativeAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-node.js\nconst createIsAnyAudioNode = (audioNodeStore, isNativeAudioNode) => {\n return (anything) => audioNodeStore.has(anything) || isNativeAudioNode(anything);\n};\n//# sourceMappingURL=is-any-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-param.js\nconst createIsAnyAudioParam = (audioParamStore, isNativeAudioParam) => {\n return (anything) => audioParamStore.has(anything) || isNativeAudioParam(anything);\n};\n//# sourceMappingURL=is-any-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-offline-audio-context.js\nconst createIsAnyOfflineAudioContext = (contextStore, isNativeOfflineAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeOfflineAudioContext(nativeContext) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-context.js\nconst createIsNativeAudioContext = (nativeAudioContextConstructor) => {\n return (anything) => {\n return nativeAudioContextConstructor !== null && anything instanceof nativeAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-node.js\nconst createIsNativeAudioNode = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioNode === \'function\' && anything instanceof window.AudioNode;\n };\n};\n//# sourceMappingURL=is-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-param.js\nconst createIsNativeAudioParam = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioParam === \'function\' && anything instanceof window.AudioParam;\n };\n};\n//# sourceMappingURL=is-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-context.js\nconst createIsNativeContext = (isNativeAudioContext, isNativeOfflineAudioContext) => {\n return (anything) => {\n return isNativeAudioContext(anything) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-offline-audio-context.js\nconst createIsNativeOfflineAudioContext = (nativeOfflineAudioContextConstructor) => {\n return (anything) => {\n return nativeOfflineAudioContextConstructor !== null && anything instanceof nativeOfflineAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-secure-context.js\nconst createIsSecureContext = (window) => window !== null && window.isSecureContext;\n//# sourceMappingURL=is-secure-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-element-audio-source-node-constructor.js\nconst createMediaElementAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaElementAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaElementAudioSourceNode = createNativeMediaElementAudioSourceNode(nativeContext, options);\n // Bug #171: Safari allows to create a MediaElementAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw TypeError();\n }\n super(context, true, nativeMediaElementAudioSourceNode, null);\n this._nativeMediaElementAudioSourceNode = nativeMediaElementAudioSourceNode;\n }\n get mediaElement() {\n return this._nativeMediaElementAudioSourceNode.mediaElement;\n }\n };\n};\n//# sourceMappingURL=media-element-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-destination-node-constructor.js\nconst media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\'\n};\nconst createMediaStreamAudioDestinationNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioDestinationNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n // Bug #173: Safari allows to create a MediaStreamAudioDestinationNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n const mergedOptions = { ...media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeMediaStreamAudioDestinationNode = createNativeMediaStreamAudioDestinationNode(nativeContext, mergedOptions);\n super(context, false, nativeMediaStreamAudioDestinationNode, null);\n this._nativeMediaStreamAudioDestinationNode = nativeMediaStreamAudioDestinationNode;\n }\n get stream() {\n return this._nativeMediaStreamAudioDestinationNode.stream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-source-node-constructor.js\nconst createMediaStreamAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamAudioSourceNode = createNativeMediaStreamAudioSourceNode(nativeContext, options);\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n super(context, true, nativeMediaStreamAudioSourceNode, null);\n this._nativeMediaStreamAudioSourceNode = nativeMediaStreamAudioSourceNode;\n }\n get mediaStream() {\n return this._nativeMediaStreamAudioSourceNode.mediaStream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-track-audio-source-node-constructor.js\nconst createMediaStreamTrackAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext) => {\n return class MediaStreamTrackAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNode(nativeContext, options);\n super(context, true, nativeMediaStreamTrackAudioSourceNode, null);\n }\n };\n};\n//# sourceMappingURL=media-stream-track-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-audio-context-constructor.js\n\n\nconst createMinimalAudioContextConstructor = (createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor) => {\n return class MinimalAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=minimal-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-base-audio-context-constructor.js\n\nconst createMinimalBaseAudioContextConstructor = (audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener) => {\n return class MinimalBaseAudioContext extends eventTargetConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext);\n this._nativeContext = _nativeContext;\n CONTEXT_STORE.set(this, _nativeContext);\n if (isNativeOfflineAudioContext(_nativeContext)) {\n unrenderedAudioWorkletNodeStore.set(_nativeContext, new Set());\n }\n this._destination = new audioDestinationNodeConstructor(this, numberOfChannels);\n this._listener = createAudioListener(this, _nativeContext);\n this._onstatechange = null;\n }\n get currentTime() {\n return this._nativeContext.currentTime;\n }\n get destination() {\n return this._destination;\n }\n get listener() {\n return this._listener;\n }\n get onstatechange() {\n return this._onstatechange;\n }\n set onstatechange(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeContext.onstatechange = wrappedListener;\n const nativeOnStateChange = this._nativeContext.onstatechange;\n this._onstatechange = nativeOnStateChange !== null && nativeOnStateChange === wrappedListener ? value : nativeOnStateChange;\n }\n get sampleRate() {\n return this._nativeContext.sampleRate;\n }\n get state() {\n return this._nativeContext.state;\n }\n };\n};\n//# sourceMappingURL=minimal-base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-promise-support.js\nconst testPromiseSupport = (nativeContext) => {\n // This 12 numbers represent the 48 bytes of an empty WAVE file with a single sample.\n const uint32Array = new Uint32Array([1179011410, 40, 1163280727, 544501094, 16, 131073, 44100, 176400, 1048580, 1635017060, 4, 0]);\n try {\n // Bug #1: Safari requires a successCallback.\n const promise = nativeContext.decodeAudioData(uint32Array.buffer, () => {\n // Ignore the success callback.\n });\n if (promise === undefined) {\n return false;\n }\n promise.catch(() => {\n // Ignore rejected errors.\n });\n return true;\n }\n catch {\n // Ignore errors.\n }\n return false;\n};\n//# sourceMappingURL=test-promise-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-offline-audio-context-constructor.js\n\n\nconst minimal_offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createMinimalOfflineAudioContextConstructor = (cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering) => {\n return class MinimalOfflineAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options) {\n const { length, numberOfChannels, sampleRate } = { ...minimal_offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=minimal-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/monitor-connections.js\nconst createMonitorConnections = (insertElementInSet, isNativeAudioNode) => {\n return (nativeAudioNode, whenConnected, whenDisconnected) => {\n const connections = new Set();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const wasDisconnected = connections.size === 0;\n if (isNativeAudioNode(destination)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n connect.call(nativeAudioNode, destination, output, input);\n insertElementInSet(connections, [destination, output, input], (connection) => connection[0] === destination && connection[1] === output && connection[2] === input, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return destination;\n }\n connect.call(nativeAudioNode, destination, output);\n insertElementInSet(connections, [destination, output], (connection) => connection[0] === destination && connection[1] === output, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return;\n };\n })(nativeAudioNode.connect);\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n const wasConnected = connections.size > 0;\n if (destinationOrOutput === undefined) {\n disconnect.apply(nativeAudioNode);\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioNode, destinationOrOutput);\n for (const connection of connections) {\n if (connection[1] === destinationOrOutput) {\n connections.delete(connection);\n }\n }\n }\n else {\n if (isNativeAudioNode(destinationOrOutput)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output, input);\n }\n else {\n // @todo TypeScript cannot infer the overloaded signature with 2 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output);\n }\n for (const connection of connections) {\n if (connection[0] === destinationOrOutput &&\n (output === undefined || connection[1] === output) &&\n (input === undefined || connection[2] === input)) {\n connections.delete(connection);\n }\n }\n }\n const isDisconnected = connections.size === 0;\n if (wasConnected && isDisconnected) {\n whenDisconnected();\n }\n };\n })(nativeAudioNode.disconnect);\n return nativeAudioNode;\n };\n};\n//# sourceMappingURL=monitor-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-option.js\nconst assignNativeAudioNodeOption = (nativeAudioNode, options, option) => {\n const value = options[option];\n if (value !== undefined && value !== nativeAudioNode[option]) {\n nativeAudioNode[option] = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-option.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-options.js\n\nconst assignNativeAudioNodeOptions = (nativeAudioNode, options) => {\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCount\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCountMode\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelInterpretation\');\n};\n//# sourceMappingURL=assign-native-audio-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-analyser-node-get-float-time-domain-data-method-support.js\nconst testAnalyserNodeGetFloatTimeDomainDataMethodSupport = (nativeAnalyserNode) => {\n return typeof nativeAnalyserNode.getFloatTimeDomainData === \'function\';\n};\n//# sourceMappingURL=test-analyser-node-get-float-time-domain-data-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-analyser-node-get-float-time-domain-data-method.js\nconst wrapAnalyserNodeGetFloatTimeDomainDataMethod = (nativeAnalyserNode) => {\n nativeAnalyserNode.getFloatTimeDomainData = (array) => {\n const byteTimeDomainData = new Uint8Array(array.length);\n nativeAnalyserNode.getByteTimeDomainData(byteTimeDomainData);\n const length = Math.max(byteTimeDomainData.length, nativeAnalyserNode.fftSize);\n for (let i = 0; i < length; i += 1) {\n array[i] = (byteTimeDomainData[i] - 128) * 0.0078125;\n }\n return array;\n };\n};\n//# sourceMappingURL=wrap-analyser-node-get-float-time-domain-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-analyser-node-factory.js\n\n\n\n\nconst createNativeAnalyserNodeFactory = (cacheTestResult, createIndexSizeError) => {\n return (nativeContext, options) => {\n const nativeAnalyserNode = nativeContext.createAnalyser();\n // Bug #37: Firefox does not create an AnalyserNode with the default properties.\n assignNativeAudioNodeOptions(nativeAnalyserNode, options);\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n if (!(options.maxDecibels > options.minDecibels)) {\n throw createIndexSizeError();\n }\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'fftSize\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'maxDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'minDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'smoothingTimeConstant\');\n // Bug #36: Safari does not support getFloatTimeDomainData() yet.\n if (!cacheTestResult(testAnalyserNodeGetFloatTimeDomainDataMethodSupport, () => testAnalyserNodeGetFloatTimeDomainDataMethodSupport(nativeAnalyserNode))) {\n wrapAnalyserNodeGetFloatTimeDomainDataMethod(nativeAnalyserNode);\n }\n return nativeAnalyserNode;\n };\n};\n//# sourceMappingURL=native-analyser-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-constructor.js\nconst createNativeAudioBufferConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioBuffer\')) {\n return window.AudioBuffer;\n }\n return null;\n};\n//# sourceMappingURL=native-audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-audio-param-value.js\nconst assignNativeAudioNodeAudioParamValue = (nativeAudioNode, options, audioParam) => {\n const value = options[audioParam];\n if (value !== undefined && value !== nativeAudioNode[audioParam].value) {\n nativeAudioNode[audioParam].value = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-audio-param-value.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-consecutive-calls.js\n\nconst wrapAudioBufferSourceNodeStartMethodConsecutiveCalls = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n let isScheduled = false;\n return (when = 0, offset = 0, duration) => {\n if (isScheduled) {\n throw createInvalidStateError();\n }\n start.call(nativeAudioBufferSourceNode, when, offset, duration);\n isScheduled = true;\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-start-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStartMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n if ((typeof duration === \'number\' && duration < 0) || offset < 0 || when < 0) {\n throw new RangeError("The parameters can\'t be negative.");\n }\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n start.call(nativeAudioScheduledSourceNode, when, offset, duration);\n };\n })(nativeAudioScheduledSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-start-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStopMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n return (when = 0) => {\n if (when < 0) {\n throw new RangeError("The parameter can\'t be negative.");\n }\n stop.call(nativeAudioScheduledSourceNode, when);\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-source-node-factory.js\n\n\n\n\n\n\nconst createNativeAudioBufferSourceNodeFactory = (addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClampling, wrapAudioBufferSourceNodeStopMethodNullifiedBuffer, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n assignNativeAudioNodeOptions(nativeAudioBufferSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeAudioBufferSourceNode, options, \'playbackRate\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'buffer\');\n // Bug #149: Safari does not yet support the detune AudioParam.\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loop\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopEnd\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopStart\');\n // Bug #69: Safari does allow calls to start() of an already scheduled AudioBufferSourceNode.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, () => testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodConsecutiveCalls(nativeAudioBufferSourceNode);\n }\n // Bug #154 & #155: Safari does not handle offsets which are equal to or greater than the duration of the buffer.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodOffsetClampingSupport, () => testAudioBufferSourceNodeStartMethodOffsetClampingSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodOffsetClampling(nativeAudioBufferSourceNode);\n }\n // Bug #162: Safari does throw an error when stop() is called on an AudioBufferSourceNode which has no buffer assigned to it.\n if (!cacheTestResult(testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, () => testAudioBufferSourceNodeStopMethodNullifiedBufferSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStopMethodNullifiedBuffer(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n};\n//# sourceMappingURL=native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-context-constructor.js\nconst createNativeAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioContext\')) {\n return window.AudioContext;\n }\n return window.hasOwnProperty(\'webkitAudioContext\') ? window.webkitAudioContext : null;\n};\n//# sourceMappingURL=native-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-destination-node.js\nconst createNativeAudioDestinationNodeFactory = (createNativeGainNode, overwriteAccessors) => {\n return (nativeContext, channelCount, isNodeOfNativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeContext.destination;\n // Bug #132: Safari does not have the correct channelCount.\n if (nativeAudioDestinationNode.channelCount !== channelCount) {\n try {\n nativeAudioDestinationNode.channelCount = channelCount;\n }\n catch {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n }\n }\n // Bug #83: Safari does not have the correct channelCountMode.\n if (isNodeOfNativeOfflineAudioContext && nativeAudioDestinationNode.channelCountMode !== \'explicit\') {\n nativeAudioDestinationNode.channelCountMode = \'explicit\';\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (nativeAudioDestinationNode.maxChannelCount === 0) {\n Object.defineProperty(nativeAudioDestinationNode, \'maxChannelCount\', {\n value: channelCount\n });\n }\n // Bug #168: No browser does yet have an AudioDestinationNode with an output.\n const gainNode = createNativeGainNode(nativeContext, {\n channelCount,\n channelCountMode: nativeAudioDestinationNode.channelCountMode,\n channelInterpretation: nativeAudioDestinationNode.channelInterpretation,\n gain: 1\n });\n overwriteAccessors(gainNode, \'channelCount\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n try {\n nativeAudioDestinationNode.channelCount = value;\n }\n catch (err) {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n if (value > nativeAudioDestinationNode.maxChannelCount) {\n throw err;\n }\n }\n });\n overwriteAccessors(gainNode, \'channelCountMode\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelCountMode = value;\n });\n overwriteAccessors(gainNode, \'channelInterpretation\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelInterpretation = value;\n });\n Object.defineProperty(gainNode, \'maxChannelCount\', {\n get: () => nativeAudioDestinationNode.maxChannelCount\n });\n // @todo This should be disconnected when the context is closed.\n gainNode.connect(nativeAudioDestinationNode);\n return gainNode;\n };\n};\n//# sourceMappingURL=native-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-constructor.js\nconst createNativeAudioWorkletNodeConstructor = (window) => {\n if (window === null) {\n return null;\n }\n return window.hasOwnProperty(\'AudioWorkletNode\') ? window.AudioWorkletNode : null;\n};\n//# sourceMappingURL=native-audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-clonability-of-audio-worklet-node-options.js\nconst testClonabilityOfAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n const { port1 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n }\n};\n//# sourceMappingURL=test-clonability-of-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-factory.js\n\nconst createNativeAudioWorkletNodeFactory = (createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections) => {\n return (nativeContext, baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, options) => {\n if (nativeAudioWorkletNodeConstructor !== null) {\n try {\n const nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeContext, name, options);\n const patchedEventListeners = new Map();\n let onprocessorerror = null;\n Object.defineProperties(nativeAudioWorkletNode, {\n /*\n * Bug #61: Overwriting the property accessors for channelCount and channelCountMode is necessary as long as some\n * browsers have no native implementation to achieve a consistent behavior.\n */\n channelCount: {\n get: () => options.channelCount,\n set: () => {\n throw createInvalidStateError();\n }\n },\n channelCountMode: {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n },\n // Bug #156: Chrome and Edge do not yet fire an ErrorEvent.\n onprocessorerror: {\n get: () => onprocessorerror,\n set: (value) => {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.addEventListener(\'processorerror\', onprocessorerror);\n }\n }\n }\n });\n nativeAudioWorkletNode.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n // Bug #178: Chrome and Edge do fire an event of type error.\n if (event.type === \'error\') {\n Object.defineProperties(event, {\n type: { value: \'processorerror\' }\n });\n unpatchedEventListener(event);\n }\n else {\n unpatchedEventListener(new ErrorEvent(args[0], { ...event }));\n }\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n addEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return addEventListener.call(nativeAudioWorkletNode, ...args);\n };\n })(nativeAudioWorkletNode.addEventListener);\n nativeAudioWorkletNode.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n removeEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return removeEventListener.call(nativeAudioWorkletNode, args[0], args[1], args[2]);\n };\n })(nativeAudioWorkletNode.removeEventListener);\n /*\n * Bug #86: Chrome and Edge do not invoke the process() function if the corresponding AudioWorkletNode is unconnected but\n * has an output.\n */\n if (options.numberOfOutputs !== 0) {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioWorkletNode.connect(nativeGainNode).connect(nativeContext.destination);\n const whenConnected = () => nativeGainNode.disconnect();\n const whenDisconnected = () => nativeGainNode.connect(nativeContext.destination);\n // @todo Disconnect the connection when the process() function of the AudioWorkletNode returns false.\n return monitorConnections(nativeAudioWorkletNode, whenConnected, whenDisconnected);\n }\n return nativeAudioWorkletNode;\n }\n catch (err) {\n // Bug #60: Chrome & Edge throw an InvalidStateError instead of a NotSupportedError.\n if (err.code === 11) {\n throw createNotSupportedError();\n }\n throw err;\n }\n }\n // Bug #61: Only Chrome & Edge have an implementation of the AudioWorkletNode yet.\n if (processorConstructor === undefined) {\n throw createNotSupportedError();\n }\n testClonabilityOfAudioWorkletNodeOptions(options);\n return createNativeAudioWorkletNodeFaker(nativeContext, baseLatency, processorConstructor, options);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/compute-buffer-size.js\nconst computeBufferSize = (baseLatency, sampleRate) => {\n if (baseLatency === null) {\n return 512;\n }\n return Math.max(512, Math.min(16384, Math.pow(2, Math.round(Math.log2(baseLatency * sampleRate)))));\n};\n//# sourceMappingURL=compute-buffer-size.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/clone-audio-worklet-node-options.js\nconst cloneAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n return new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n port1.onmessage = ({ data }) => {\n port1.close();\n port2.close();\n resolve(data);\n };\n port1.onmessageerror = ({ data }) => {\n port1.close();\n port2.close();\n reject(data);\n };\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port2.postMessage(audioWorkletNodeOptions);\n });\n};\n//# sourceMappingURL=clone-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor-promise.js\n\nconst createAudioWorkletProcessorPromise = async (processorConstructor, audioWorkletNodeOptions) => {\n const clonedAudioWorkletNodeOptions = await cloneAudioWorkletNodeOptions(audioWorkletNodeOptions);\n return new processorConstructor(clonedAudioWorkletNodeOptions);\n};\n//# sourceMappingURL=create-audio-worklet-processor-promise.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor.js\n\n\nconst createAudioWorkletProcessor = (nativeContext, nativeAudioWorkletNode, processorConstructor, audioWorkletNodeOptions) => {\n let nodeToProcessorMap = NODE_TO_PROCESSOR_MAPS.get(nativeContext);\n if (nodeToProcessorMap === undefined) {\n nodeToProcessorMap = new WeakMap();\n NODE_TO_PROCESSOR_MAPS.set(nativeContext, nodeToProcessorMap);\n }\n const audioWorkletProcessorPromise = createAudioWorkletProcessorPromise(processorConstructor, audioWorkletNodeOptions);\n nodeToProcessorMap.set(nativeAudioWorkletNode, audioWorkletProcessorPromise);\n return audioWorkletProcessorPromise;\n};\n//# sourceMappingURL=create-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-faker-factory.js\n\n\n\n\n\n\n\nconst createNativeAudioWorkletNodeFakerFactory = (connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections) => {\n return (nativeContext, baseLatency, processorConstructor, options) => {\n if (options.numberOfInputs === 0 && options.numberOfOutputs === 0) {\n throw createNotSupportedError();\n }\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // @todo Check if any of the channelCount values is greater than the implementation\'s maximum number of channels.\n if (outputChannelCount.some((channelCount) => channelCount < 1)) {\n throw createNotSupportedError();\n }\n if (outputChannelCount.length !== options.numberOfOutputs) {\n throw createIndexSizeError();\n }\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (options.channelCountMode !== \'explicit\') {\n throw createNotSupportedError();\n }\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (numberOfInputChannels + numberOfParameters > 6 || numberOfOutputChannels > 6) {\n throw createNotSupportedError();\n }\n const messageChannel = new MessageChannel();\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = [];\n if (processorConstructor.parameterDescriptors !== undefined) {\n for (const { defaultValue, maxValue, minValue, name } of processorConstructor.parameterDescriptors) {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: options.parameterData[name] !== undefined\n ? options.parameterData[name]\n : defaultValue === undefined\n ? 0\n : defaultValue\n });\n Object.defineProperties(constantSourceNode.offset, {\n defaultValue: {\n get: () => (defaultValue === undefined ? 0 : defaultValue)\n },\n maxValue: {\n get: () => (maxValue === undefined ? MOST_POSITIVE_SINGLE_FLOAT : maxValue)\n },\n minValue: {\n get: () => (minValue === undefined ? MOST_NEGATIVE_SINGLE_FLOAT : minValue)\n }\n });\n constantSourceNodes.push(constantSourceNode);\n }\n }\n const inputChannelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, numberOfInputChannels + numberOfParameters, \n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n Math.max(1, numberOfOutputChannels));\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < options.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n const parameterMap = new ReadOnlyMap(processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.map(({ name }, index) => {\n const constantSourceNode = constantSourceNodes[index];\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n return [name, constantSourceNode.offset];\n }));\n inputChannelMergerNode.connect(scriptProcessorNode);\n let channelInterpretation = options.channelInterpretation;\n let onprocessorerror = null;\n // Bug #87: Expose at least one output to make this node connectable.\n const outputAudioNodes = options.numberOfOutputs === 0 ? [scriptProcessorNode] : outputChannelMergerNodes;\n const nativeAudioWorkletNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return options.channelCount;\n },\n set channelCount(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelCountMode() {\n return options.channelCountMode;\n },\n set channelCountMode(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelInterpretation() {\n return channelInterpretation;\n },\n set channelInterpretation(value) {\n for (const gainNode of gainNodes) {\n gainNode.channelInterpretation = value;\n }\n channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return gainNodes;\n },\n get numberOfInputs() {\n return options.numberOfInputs;\n },\n get numberOfOutputs() {\n return options.numberOfOutputs;\n },\n get onprocessorerror() {\n return onprocessorerror;\n },\n set onprocessorerror(value) {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.addEventListener(\'processorerror\', onprocessorerror);\n }\n },\n get parameters() {\n return parameterMap;\n },\n get port() {\n return messageChannel.port2;\n },\n addEventListener(...args) {\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n connect: connectMultipleOutputs.bind(null, outputAudioNodes),\n disconnect: disconnectMultipleOutputs.bind(null, outputAudioNodes),\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n const patchedEventListeners = new Map();\n messageChannel.port1.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => unpatchedEventListener(event));\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n return addEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.addEventListener);\n messageChannel.port1.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n return removeEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.removeEventListener);\n let onmessage = null;\n Object.defineProperty(messageChannel.port1, \'onmessage\', {\n get: () => onmessage,\n set: (value) => {\n if (typeof onmessage === \'function\') {\n messageChannel.port1.removeEventListener(\'message\', onmessage);\n }\n onmessage = typeof value === \'function\' ? value : null;\n if (typeof onmessage === \'function\') {\n messageChannel.port1.addEventListener(\'message\', onmessage);\n messageChannel.port1.start();\n }\n }\n });\n processorConstructor.prototype.port = messageChannel.port1;\n let audioWorkletProcessor = null;\n const audioWorkletProcessorPromise = createAudioWorkletProcessor(nativeContext, nativeAudioWorkletNodeFaker, processorConstructor, options);\n audioWorkletProcessorPromise.then((dWrkltPrcssr) => (audioWorkletProcessor = dWrkltPrcssr));\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.reduce((prmtrs, { name }) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n let isActive = true;\n const disconnectOutputsGraph = () => {\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.disconnect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.disconnect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n };\n const activeInputIndexes = new Map();\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer, outputBuffer }) => {\n if (audioWorkletProcessor !== null) {\n const activeInputs = getActiveAudioWorkletNodeInputs(nativeAudioWorkletNodeFaker);\n for (let i = 0; i < bufferSize; i += 128) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(inputBuffer, inputs[j], k, k, i);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(inputBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n const activeInput = activeInputs[index];\n if (activeInput.size > 0) {\n activeInputIndexes.set(index, bufferSize / 128);\n return input;\n }\n const count = activeInputIndexes.get(index);\n if (count === undefined) {\n return [];\n }\n if (input.every((channelData) => channelData.every((sample) => sample === 0))) {\n if (count === 1) {\n activeInputIndexes.delete(index);\n }\n else {\n activeInputIndexes.set(index, count - 1);\n }\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(nativeContext.currentTime + i / nativeContext.sampleRate, nativeContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n isActive = activeSourceFlag;\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(outputBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n catch (error) {\n isActive = false;\n nativeAudioWorkletNodeFaker.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n }\n if (!isActive) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n gainNodes[j].disconnect(inputChannelSplitterNodes[j]);\n for (let k = 0; k < options.channelCount; k += 1) {\n inputChannelSplitterNodes[i].disconnect(inputChannelMergerNode, k, j * options.channelCount + k);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n const length = processorConstructor.parameterDescriptors.length;\n for (let j = 0; j < length; j += 1) {\n const constantSourceNode = constantSourceNodes[j];\n constantSourceNode.disconnect(inputChannelMergerNode, 0, numberOfInputChannels + j);\n constantSourceNode.stop();\n }\n }\n inputChannelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n if (isConnected) {\n disconnectOutputsGraph();\n }\n else {\n disconnectFakeGraph();\n }\n break;\n }\n }\n }\n };\n let isConnected = false;\n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n const connectFakeGraph = () => scriptProcessorNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnectFakeGraph = () => {\n scriptProcessorNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n const whenConnected = () => {\n if (isActive) {\n disconnectFakeGraph();\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.connect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n }\n isConnected = true;\n };\n const whenDisconnected = () => {\n if (isActive) {\n connectFakeGraph();\n disconnectOutputsGraph();\n }\n isConnected = false;\n };\n connectFakeGraph();\n return monitorConnections(nativeAudioWorkletNodeFaker, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-biquad-filter-node.js\n\n\n\nconst createNativeBiquadFilterNode = (nativeContext, options) => {\n const nativeBiquadFilterNode = nativeContext.createBiquadFilter();\n assignNativeAudioNodeOptions(nativeBiquadFilterNode, options);\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'Q\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'frequency\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'gain\');\n assignNativeAudioNodeOption(nativeBiquadFilterNode, options, \'type\');\n return nativeBiquadFilterNode;\n};\n//# sourceMappingURL=native-biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-merger-node-factory.js\n\nconst createNativeChannelMergerNodeFactory = (nativeAudioContextConstructor, wrapChannelMergerNode) => {\n return (nativeContext, options) => {\n const nativeChannelMergerNode = nativeContext.createChannelMerger(options.numberOfInputs);\n /*\n * Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n wrapChannelMergerNode(nativeContext, nativeChannelMergerNode);\n }\n assignNativeAudioNodeOptions(nativeChannelMergerNode, options);\n return nativeChannelMergerNode;\n };\n};\n//# sourceMappingURL=native-channel-merger-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-channel-splitter-node.js\n\nconst wrapChannelSplitterNode = (channelSplitterNode) => {\n const channelCount = channelSplitterNode.numberOfOutputs;\n // Bug #97: Safari does not throw an error when attempting to change the channelCount to something other than its initial value.\n Object.defineProperty(channelSplitterNode, \'channelCount\', {\n get: () => channelCount,\n set: (value) => {\n if (value !== channelCount) {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #30: Safari does not throw an error when attempting to change the channelCountMode to something other than explicit.\n Object.defineProperty(channelSplitterNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: (value) => {\n if (value !== \'explicit\') {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #32: Safari does not throw an error when attempting to change the channelInterpretation to something other than discrete.\n Object.defineProperty(channelSplitterNode, \'channelInterpretation\', {\n get: () => \'discrete\',\n set: (value) => {\n if (value !== \'discrete\') {\n throw createInvalidStateError();\n }\n }\n });\n};\n//# sourceMappingURL=wrap-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-splitter-node.js\n\n\nconst createNativeChannelSplitterNode = (nativeContext, options) => {\n const nativeChannelSplitterNode = nativeContext.createChannelSplitter(options.numberOfOutputs);\n // Bug #96: Safari does not have the correct channelCount.\n // Bug #29: Safari does not have the correct channelCountMode.\n // Bug #31: Safari does not have the correct channelInterpretation.\n assignNativeAudioNodeOptions(nativeChannelSplitterNode, options);\n // Bug #29, #30, #31, #32, #96 & #97: Only Chrome, Edge & Firefox partially support the spec yet.\n wrapChannelSplitterNode(nativeChannelSplitterNode);\n return nativeChannelSplitterNode;\n};\n//# sourceMappingURL=native-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-factory.js\n\n\n\n\nconst createNativeConstantSourceNodeFactory = (addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport) => {\n return (nativeContext, options) => {\n // Bug #62: Safari does not support ConstantSourceNodes.\n if (nativeContext.createConstantSource === undefined) {\n return createNativeConstantSourceNodeFaker(nativeContext, options);\n }\n const nativeConstantSourceNode = nativeContext.createConstantSource();\n assignNativeAudioNodeOptions(nativeConstantSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeConstantSourceNode, options, \'offset\');\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the ConstantSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n};\n//# sourceMappingURL=native-constant-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/intercept-connections.js\nconst interceptConnections = (original, interceptor) => {\n original.connect = interceptor.connect.bind(interceptor);\n original.disconnect = interceptor.disconnect.bind(interceptor);\n return original;\n};\n//# sourceMappingURL=intercept-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-faker-factory.js\n\nconst createNativeConstantSourceNodeFakerFactory = (addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections) => {\n return (nativeContext, { offset, ...audioNodeOptions }) => {\n const audioBuffer = nativeContext.createBuffer(1, 2, 44100);\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const gainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: offset });\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n const channelData = audioBuffer.getChannelData(0);\n // Bug #95: Safari does not play or loop one sample buffers.\n channelData[0] = 1;\n channelData[1] = 1;\n audioBufferSourceNode.buffer = audioBuffer;\n audioBufferSourceNode.loop = true;\n const nativeConstantSourceNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return gainNode.channelCount;\n },\n set channelCount(value) {\n gainNode.channelCount = value;\n },\n get channelCountMode() {\n return gainNode.channelCountMode;\n },\n set channelCountMode(value) {\n gainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return gainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n gainNode.channelInterpretation = value;\n },\n get context() {\n return gainNode.context;\n },\n get inputs() {\n return [];\n },\n get numberOfInputs() {\n return audioBufferSourceNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return gainNode.numberOfOutputs;\n },\n get offset() {\n return gainNode.gain;\n },\n get onended() {\n return audioBufferSourceNode.onended;\n },\n set onended(value) {\n audioBufferSourceNode.onended = value;\n },\n addEventListener(...args) {\n return audioBufferSourceNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return audioBufferSourceNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return audioBufferSourceNode.removeEventListener(args[0], args[1], args[2]);\n },\n start(when = 0) {\n audioBufferSourceNode.start.call(audioBufferSourceNode, when);\n },\n stop(when = 0) {\n audioBufferSourceNode.stop.call(audioBufferSourceNode, when);\n }\n };\n const whenConnected = () => audioBufferSourceNode.connect(gainNode);\n const whenDisconnected = () => audioBufferSourceNode.disconnect(gainNode);\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, audioBufferSourceNode);\n return monitorConnections(interceptConnections(nativeConstantSourceNodeFaker, gainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-constant-source-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-convolver-node-factory.js\n\n\nconst createNativeConvolverNodeFactory = (createNotSupportedError, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeConvolverNode = nativeContext.createConvolver();\n assignNativeAudioNodeOptions(nativeConvolverNode, options);\n // The normalize property needs to be set before setting the buffer.\n if (options.disableNormalization === nativeConvolverNode.normalize) {\n nativeConvolverNode.normalize = !options.disableNormalization;\n }\n assignNativeAudioNodeOption(nativeConvolverNode, options, \'buffer\');\n // Bug #113: Safari does allow to set the channelCount to a value larger than 2.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCount\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value > 2) {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n // Bug #114: Safari allows to set the channelCountMode to \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCountMode\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n return nativeConvolverNode;\n };\n};\n//# sourceMappingURL=native-convolver-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-delay-node.js\n\n\nconst createNativeDelayNode = (nativeContext, options) => {\n const nativeDelayNode = nativeContext.createDelay(options.maxDelayTime);\n assignNativeAudioNodeOptions(nativeDelayNode, options);\n assignNativeAudioNodeAudioParamValue(nativeDelayNode, options, \'delayTime\');\n return nativeDelayNode;\n};\n//# sourceMappingURL=native-delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-dynamics-compressor-node-factory.js\n\n\nconst createNativeDynamicsCompressorNodeFactory = (createNotSupportedError) => {\n return (nativeContext, options) => {\n const nativeDynamicsCompressorNode = nativeContext.createDynamicsCompressor();\n assignNativeAudioNodeOptions(nativeDynamicsCompressorNode, options);\n // Bug #108: Safari allows a channelCount of three and above.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'attack\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'knee\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'ratio\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'release\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'threshold\');\n return nativeDynamicsCompressorNode;\n };\n};\n//# sourceMappingURL=native-dynamics-compressor-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-gain-node.js\n\n\nconst createNativeGainNode = (nativeContext, options) => {\n const nativeGainNode = nativeContext.createGain();\n assignNativeAudioNodeOptions(nativeGainNode, options);\n assignNativeAudioNodeAudioParamValue(nativeGainNode, options, \'gain\');\n return nativeGainNode;\n};\n//# sourceMappingURL=native-gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-factory.js\n\nconst createNativeIIRFilterNodeFactory = (createNativeIIRFilterNodeFaker) => {\n return (nativeContext, baseLatency, options) => {\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeContext.createIIRFilter === undefined) {\n return createNativeIIRFilterNodeFaker(nativeContext, baseLatency, options);\n }\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n const nativeIIRFilterNode = nativeContext.createIIRFilter(options.feedforward, options.feedback);\n assignNativeAudioNodeOptions(nativeIIRFilterNode, options);\n return nativeIIRFilterNode;\n };\n};\n//# sourceMappingURL=native-iir-filter-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-faker-factory.js\n\n\n\nfunction divide(a, b) {\n const denominator = b[0] * b[0] + b[1] * b[1];\n return [(a[0] * b[0] + a[1] * b[1]) / denominator, (a[1] * b[0] - a[0] * b[1]) / denominator];\n}\nfunction multiply(a, b) {\n return [a[0] * b[0] - a[1] * b[1], a[0] * b[1] + a[1] * b[0]];\n}\nfunction evaluatePolynomial(coefficient, z) {\n let result = [0, 0];\n for (let i = coefficient.length - 1; i >= 0; i -= 1) {\n result = multiply(result, z);\n result[0] += coefficient[i];\n }\n return result;\n}\nconst createNativeIIRFilterNodeFakerFactory = (createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError) => {\n return (nativeContext, baseLatency, { channelCount, channelCountMode, channelInterpretation, feedback, feedforward }) => {\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (feedbackLength === 0 || feedbackLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedback[0] === 0) {\n throw createInvalidStateError();\n }\n if (feedforwardLength === 0 || feedforwardLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedforward[0] === 0) {\n throw createInvalidStateError();\n }\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedforwardLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedbackLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, channelCount, channelCount);\n scriptProcessorNode.channelCount = channelCount;\n scriptProcessorNode.channelCountMode = channelCountMode;\n scriptProcessorNode.channelInterpretation = channelInterpretation;\n const bufferLength = 32;\n const bufferIndexes = [];\n const xBuffers = [];\n const yBuffers = [];\n for (let i = 0; i < channelCount; i += 1) {\n bufferIndexes.push(0);\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n xBuffer.fill(0);\n yBuffer.fill(0);\n xBuffers.push(xBuffer);\n yBuffers.push(yBuffer);\n }\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = (event) => {\n const inputBuffer = event.inputBuffer;\n const outputBuffer = event.outputBuffer;\n const numberOfChannels = inputBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = inputBuffer.getChannelData(i);\n const output = outputBuffer.getChannelData(i);\n bufferIndexes[i] = filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffers[i], yBuffers[i], bufferIndexes[i], bufferLength, input, output);\n }\n };\n const nyquist = nativeContext.sampleRate / 2;\n const nativeIIRFilterNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return scriptProcessorNode.channelCount;\n },\n set channelCount(value) {\n scriptProcessorNode.channelCount = value;\n },\n get channelCountMode() {\n return scriptProcessorNode.channelCountMode;\n },\n set channelCountMode(value) {\n scriptProcessorNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return scriptProcessorNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n scriptProcessorNode.channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return [scriptProcessorNode];\n },\n get numberOfInputs() {\n return scriptProcessorNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return scriptProcessorNode.numberOfOutputs;\n },\n addEventListener(...args) {\n // @todo Dissallow adding an audioprocess listener.\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n const length = frequencyHz.length;\n for (let i = 0; i < length; i += 1) {\n const omega = -Math.PI * (frequencyHz[i] / nyquist);\n const z = [Math.cos(omega), Math.sin(omega)];\n const numerator = evaluatePolynomial(convertedFeedforward, z);\n const denominator = evaluatePolynomial(convertedFeedback, z);\n const response = divide(numerator, denominator);\n magResponse[i] = Math.sqrt(response[0] * response[0] + response[1] * response[1]);\n phaseResponse[i] = Math.atan2(response[1], response[0]);\n }\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n return interceptConnections(nativeIIRFilterNodeFaker, scriptProcessorNode);\n };\n};\n//# sourceMappingURL=native-iir-filter-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-element-audio-source-node.js\nconst createNativeMediaElementAudioSourceNode = (nativeAudioContext, options) => {\n return nativeAudioContext.createMediaElementSource(options.mediaElement);\n};\n//# sourceMappingURL=native-media-element-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-destination-node.js\n\nconst createNativeMediaStreamAudioDestinationNode = (nativeAudioContext, options) => {\n const nativeMediaStreamAudioDestinationNode = nativeAudioContext.createMediaStreamDestination();\n assignNativeAudioNodeOptions(nativeMediaStreamAudioDestinationNode, options);\n // Bug #174: Safari does expose a wrong numberOfOutputs.\n if (nativeMediaStreamAudioDestinationNode.numberOfOutputs === 1) {\n Object.defineProperty(nativeMediaStreamAudioDestinationNode, \'numberOfOutputs\', { get: () => 0 });\n }\n return nativeMediaStreamAudioDestinationNode;\n};\n//# sourceMappingURL=native-media-stream-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-source-node.js\nconst createNativeMediaStreamAudioSourceNode = (nativeAudioContext, { mediaStream }) => {\n const audioStreamTracks = mediaStream.getAudioTracks();\n /*\n * Bug #151: Safari does not use the audio track as input anymore if it gets removed from the mediaStream after construction.\n * Bug #159: Safari picks the first audio track if the MediaStream has more than one audio track.\n */\n audioStreamTracks.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n const filteredAudioStreamTracks = audioStreamTracks.slice(0, 1);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(new MediaStream(filteredAudioStreamTracks));\n /*\n * Bug #151 & #159: The given mediaStream gets reconstructed before it gets passed to the native node which is why the accessor needs\n * to be overwritten as it would otherwise expose the reconstructed version.\n */\n Object.defineProperty(nativeMediaStreamAudioSourceNode, \'mediaStream\', { value: mediaStream });\n return nativeMediaStreamAudioSourceNode;\n};\n//# sourceMappingURL=native-media-stream-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-track-audio-source-node-factory.js\nconst createNativeMediaStreamTrackAudioSourceNodeFactory = (createInvalidStateError, isNativeOfflineAudioContext) => {\n return (nativeAudioContext, { mediaStreamTrack }) => {\n // Bug #121: Only Firefox does yet support the MediaStreamTrackAudioSourceNode.\n if (typeof nativeAudioContext.createMediaStreamTrackSource === \'function\') {\n return nativeAudioContext.createMediaStreamTrackSource(mediaStreamTrack);\n }\n const mediaStream = new MediaStream([mediaStreamTrack]);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(mediaStream);\n // Bug #120: Firefox does not throw an error if the mediaStream has no audio track.\n if (mediaStreamTrack.kind !== \'audio\') {\n throw createInvalidStateError();\n }\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeAudioContext)) {\n throw new TypeError();\n }\n return nativeMediaStreamAudioSourceNode;\n };\n};\n//# sourceMappingURL=native-media-stream-track-audio-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-offline-audio-context-constructor.js\nconst createNativeOfflineAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'OfflineAudioContext\')) {\n return window.OfflineAudioContext;\n }\n return window.hasOwnProperty(\'webkitOfflineAudioContext\') ? window.webkitOfflineAudioContext : null;\n};\n//# sourceMappingURL=native-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-oscillator-node-factory.js\n\n\n\n\n\nconst createNativeOscillatorNodeFactory = (addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeOscillatorNode = nativeContext.createOscillator();\n assignNativeAudioNodeOptions(nativeOscillatorNode, options);\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'frequency\');\n if (options.periodicWave !== undefined) {\n nativeOscillatorNode.setPeriodicWave(options.periodicWave);\n }\n else {\n assignNativeAudioNodeOption(nativeOscillatorNode, options, \'type\');\n }\n // Bug #44: Only Chrome & Edge throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeOscillatorNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #175: Safari will not fire an ended event if the OscillatorNode is unconnected.\n addSilentConnection(nativeContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n};\n//# sourceMappingURL=native-oscillator-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-factory.js\n\n\n\nconst createNativePannerNodeFactory = (createNativePannerNodeFaker) => {\n return (nativeContext, options) => {\n const nativePannerNode = nativeContext.createPanner();\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (nativePannerNode.orientationX === undefined) {\n return createNativePannerNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativePannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationZ\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionZ\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneInnerAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterGain\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'distanceModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'maxDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'panningModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'refDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'rolloffFactor\');\n return nativePannerNode;\n };\n};\n//# sourceMappingURL=native-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-faker-factory.js\n\n\nconst createNativePannerNodeFakerFactory = (connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections) => {\n return (nativeContext, { coneInnerAngle, coneOuterAngle, coneOuterGain, distanceModel, maxDistance, orientationX, orientationY, orientationZ, panningModel, positionX, positionY, positionZ, refDistance, rolloffFactor, ...audioNodeOptions }) => {\n const pannerNode = nativeContext.createPanner();\n // Bug #125: Safari does not throw an error yet.\n if (audioNodeOptions.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #126: Safari does not throw an error yet.\n if (audioNodeOptions.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeOptions(pannerNode, audioNodeOptions);\n const SINGLE_CHANNEL_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\'\n };\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const orientationXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 1 });\n const orientationYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const orientationZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 6, 1);\n const waveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n curve: new Float32Array([1, 1]),\n oversample: \'none\'\n });\n let lastOrientation = [orientationX, orientationY, orientationZ];\n let lastPosition = [positionX, positionY, positionZ];\n const buffer = new Float32Array(1);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n pannerNode.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n pannerNode.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n Object.defineProperty(orientationYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(orientationZGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionXGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionZGainNode.gain, \'defaultValue\', { get: () => 0 });\n const nativePannerNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return pannerNode.channelCount;\n },\n set channelCount(value) {\n // Bug #125: Safari does not throw an error yet.\n if (value > 2) {\n throw createNotSupportedError();\n }\n inputGainNode.channelCount = value;\n pannerNode.channelCount = value;\n },\n get channelCountMode() {\n return pannerNode.channelCountMode;\n },\n set channelCountMode(value) {\n // Bug #126: Safari does not throw an error yet.\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n pannerNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return pannerNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n pannerNode.channelInterpretation = value;\n },\n get coneInnerAngle() {\n return pannerNode.coneInnerAngle;\n },\n set coneInnerAngle(value) {\n pannerNode.coneInnerAngle = value;\n },\n get coneOuterAngle() {\n return pannerNode.coneOuterAngle;\n },\n set coneOuterAngle(value) {\n pannerNode.coneOuterAngle = value;\n },\n get coneOuterGain() {\n return pannerNode.coneOuterGain;\n },\n set coneOuterGain(value) {\n // Bug #127: Safari does not throw an InvalidStateError yet.\n if (value < 0 || value > 1) {\n throw createInvalidStateError();\n }\n pannerNode.coneOuterGain = value;\n },\n get context() {\n return pannerNode.context;\n },\n get distanceModel() {\n return pannerNode.distanceModel;\n },\n set distanceModel(value) {\n pannerNode.distanceModel = value;\n },\n get inputs() {\n return [inputGainNode];\n },\n get maxDistance() {\n return pannerNode.maxDistance;\n },\n set maxDistance(value) {\n // Bug #128: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.maxDistance = value;\n },\n get numberOfInputs() {\n return pannerNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return pannerNode.numberOfOutputs;\n },\n get orientationX() {\n return orientationXGainNode.gain;\n },\n get orientationY() {\n return orientationYGainNode.gain;\n },\n get orientationZ() {\n return orientationZGainNode.gain;\n },\n get panningModel() {\n return pannerNode.panningModel;\n },\n set panningModel(value) {\n pannerNode.panningModel = value;\n },\n get positionX() {\n return positionXGainNode.gain;\n },\n get positionY() {\n return positionYGainNode.gain;\n },\n get positionZ() {\n return positionZGainNode.gain;\n },\n get refDistance() {\n return pannerNode.refDistance;\n },\n set refDistance(value) {\n // Bug #129: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.refDistance = value;\n },\n get rolloffFactor() {\n return pannerNode.rolloffFactor;\n },\n set rolloffFactor(value) {\n // Bug #130: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.rolloffFactor = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (coneInnerAngle !== nativePannerNodeFaker.coneInnerAngle) {\n nativePannerNodeFaker.coneInnerAngle = coneInnerAngle;\n }\n if (coneOuterAngle !== nativePannerNodeFaker.coneOuterAngle) {\n nativePannerNodeFaker.coneOuterAngle = coneOuterAngle;\n }\n if (coneOuterGain !== nativePannerNodeFaker.coneOuterGain) {\n nativePannerNodeFaker.coneOuterGain = coneOuterGain;\n }\n if (distanceModel !== nativePannerNodeFaker.distanceModel) {\n nativePannerNodeFaker.distanceModel = distanceModel;\n }\n if (maxDistance !== nativePannerNodeFaker.maxDistance) {\n nativePannerNodeFaker.maxDistance = maxDistance;\n }\n if (orientationX !== nativePannerNodeFaker.orientationX.value) {\n nativePannerNodeFaker.orientationX.value = orientationX;\n }\n if (orientationY !== nativePannerNodeFaker.orientationY.value) {\n nativePannerNodeFaker.orientationY.value = orientationY;\n }\n if (orientationZ !== nativePannerNodeFaker.orientationZ.value) {\n nativePannerNodeFaker.orientationZ.value = orientationZ;\n }\n if (panningModel !== nativePannerNodeFaker.panningModel) {\n nativePannerNodeFaker.panningModel = panningModel;\n }\n if (positionX !== nativePannerNodeFaker.positionX.value) {\n nativePannerNodeFaker.positionX.value = positionX;\n }\n if (positionY !== nativePannerNodeFaker.positionY.value) {\n nativePannerNodeFaker.positionY.value = positionY;\n }\n if (positionZ !== nativePannerNodeFaker.positionZ.value) {\n nativePannerNodeFaker.positionZ.value = positionZ;\n }\n if (refDistance !== nativePannerNodeFaker.refDistance) {\n nativePannerNodeFaker.refDistance = refDistance;\n }\n if (rolloffFactor !== nativePannerNodeFaker.rolloffFactor) {\n nativePannerNodeFaker.rolloffFactor = rolloffFactor;\n }\n if (lastOrientation[0] !== 1 || lastOrientation[1] !== 0 || lastOrientation[2] !== 0) {\n pannerNode.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n if (lastPosition[0] !== 0 || lastPosition[1] !== 0 || lastPosition[2] !== 0) {\n pannerNode.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n const whenConnected = () => {\n inputGainNode.connect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n connectNativeAudioNodeToNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.connect(orientationXGainNode).connect(channelMergerNode, 0, 0);\n waveShaperNode.connect(orientationYGainNode).connect(channelMergerNode, 0, 1);\n waveShaperNode.connect(orientationZGainNode).connect(channelMergerNode, 0, 2);\n waveShaperNode.connect(positionXGainNode).connect(channelMergerNode, 0, 3);\n waveShaperNode.connect(positionYGainNode).connect(channelMergerNode, 0, 4);\n waveShaperNode.connect(positionZGainNode).connect(channelMergerNode, 0, 5);\n channelMergerNode.connect(scriptProcessorNode).connect(nativeContext.destination);\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n disconnectNativeAudioNodeFromNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.disconnect(orientationXGainNode);\n orientationXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationYGainNode);\n orientationYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationZGainNode);\n orientationZGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionXGainNode);\n positionXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionYGainNode);\n positionYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionZGainNode);\n positionZGainNode.disconnect(channelMergerNode);\n channelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.disconnect(nativeContext.destination);\n };\n return monitorConnections(interceptConnections(nativePannerNodeFaker, pannerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-periodic-wave-factory.js\nconst createNativePeriodicWaveFactory = (createIndexSizeError) => {\n return (nativeContext, { disableNormalization, imag, real }) => {\n // Bug #180: Safari does not allow to use ordinary arrays.\n const convertedImag = imag instanceof Float32Array ? imag : new Float32Array(imag);\n const convertedReal = real instanceof Float32Array ? real : new Float32Array(real);\n const nativePeriodicWave = nativeContext.createPeriodicWave(convertedReal, convertedImag, { disableNormalization });\n // Bug #181: Safari does not throw an IndexSizeError so far if the given arrays have less than two values.\n if (Array.from(imag).length < 2) {\n throw createIndexSizeError();\n }\n return nativePeriodicWave;\n };\n};\n//# sourceMappingURL=native-periodic-wave-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-script-processor-node.js\nconst createNativeScriptProcessorNode = (nativeContext, bufferSize, numberOfInputChannels, numberOfOutputChannels) => {\n return nativeContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels); // tslint:disable-line deprecation\n};\n//# sourceMappingURL=native-script-processor-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-factory.js\n\n\nconst createNativeStereoPannerNodeFactory = (createNativeStereoPannerNodeFaker, createNotSupportedError) => {\n return (nativeContext, options) => {\n const channelCountMode = options.channelCountMode;\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n if (channelCountMode === \'clamped-max\') {\n throw createNotSupportedError();\n }\n // Bug #105: Safari does not support the StereoPannerNode.\n if (nativeContext.createStereoPanner === undefined) {\n return createNativeStereoPannerNodeFaker(nativeContext, options);\n }\n const nativeStereoPannerNode = nativeContext.createStereoPanner();\n assignNativeAudioNodeOptions(nativeStereoPannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativeStereoPannerNode, options, \'pan\');\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n Object.defineProperty(nativeStereoPannerNode, \'channelCountMode\', {\n get: () => channelCountMode,\n set: (value) => {\n if (value !== channelCountMode) {\n throw createNotSupportedError();\n }\n }\n });\n return nativeStereoPannerNode;\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-faker-factory.js\n\nconst createNativeStereoPannerNodeFakerFactory = (createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections) => {\n // The curve has a size of 14bit plus 1 value to have an exact representation for zero. This value has been determined experimentally.\n const CURVE_SIZE = 16385;\n const DC_CURVE = new Float32Array([1, 1]);\n const HALF_PI = Math.PI / 2;\n const SINGLE_CHANNEL_OPTIONS = { channelCount: 1, channelCountMode: \'explicit\', channelInterpretation: \'discrete\' };\n const SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS = { ...SINGLE_CHANNEL_OPTIONS, oversample: \'none\' };\n const buildInternalGraphForMono = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightWaveShaperCurve = new Float32Array(CURVE_SIZE);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n const x = (i / (CURVE_SIZE - 1)) * HALF_PI;\n leftWaveShaperCurve[i] = Math.cos(x);\n rightWaveShaperCurve[i] = Math.sin(x);\n }\n const leftGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: leftWaveShaperCurve }));\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: rightWaveShaperCurve }));\n return {\n connectGraph() {\n inputGainNode.connect(leftGainNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.connect(rightGainNode);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.connect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.connect(leftGainNode.gain);\n rightWaveShaperNode.connect(rightGainNode.gain);\n leftGainNode.connect(channelMergerNode, 0, 0);\n rightGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(leftGainNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.disconnect(rightGainNode);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.disconnect(leftGainNode.gain);\n rightWaveShaperNode.disconnect(rightGainNode.gain);\n leftGainNode.disconnect(channelMergerNode, 0, 0);\n rightGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraphForStereo = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const leftInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const centerIndex = Math.floor(CURVE_SIZE / 2);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n if (i > centerIndex) {\n const x = ((i - centerIndex) / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n leftInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n rightInputForLeftOutputWaveShaperCurve[i] = 0;\n rightInputForRightOutputWaveShaperCurve[i] = 1;\n }\n else {\n const x = (i / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = 1;\n leftInputForRightOutputWaveShaperCurve[i] = 0;\n rightInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n rightInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n }\n }\n const channelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 2\n });\n const leftInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForLeftOutputWaveShaperCurve\n });\n const leftInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForRightOutputWaveShaperCurve\n });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForLeftOutputWaveShaperCurve\n });\n const rightInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForRightOutputWaveShaperCurve\n });\n return {\n connectGraph() {\n inputGainNode.connect(channelSplitterNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.connect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.connect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.connect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.connect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.connect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.connect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.connect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.connect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(channelSplitterNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.disconnect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.disconnect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.disconnect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.disconnect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.disconnect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.disconnect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.disconnect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.disconnect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraph = (nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode) => {\n if (channelCount === 1) {\n return buildInternalGraphForMono(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n if (channelCount === 2) {\n return buildInternalGraphForStereo(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n throw createNotSupportedError();\n };\n return (nativeContext, { channelCount, channelCountMode, pan, ...audioNodeOptions }) => {\n if (channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...audioNodeOptions,\n channelCount: 1,\n channelCountMode,\n numberOfInputs: 2\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, channelCount, channelCountMode, gain: 1 });\n const panGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: pan\n });\n let { connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode);\n Object.defineProperty(panGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(panGainNode.gain, \'maxValue\', { get: () => 1 });\n Object.defineProperty(panGainNode.gain, \'minValue\', { get: () => -1 });\n const nativeStereoPannerNodeFakerFactory = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return inputGainNode.channelCount;\n },\n set channelCount(value) {\n if (inputGainNode.channelCount !== value) {\n if (isConnected) {\n disconnectGraph();\n }\n ({ connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, value, inputGainNode, panGainNode, channelMergerNode));\n if (isConnected) {\n connectGraph();\n }\n }\n inputGainNode.channelCount = value;\n },\n get channelCountMode() {\n return inputGainNode.channelCountMode;\n },\n set channelCountMode(value) {\n if (value === \'clamped-max\' || value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return inputGainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n },\n get context() {\n return inputGainNode.context;\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return inputGainNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return inputGainNode.numberOfOutputs;\n },\n get pan() {\n return panGainNode.gain;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n let isConnected = false;\n const whenConnected = () => {\n connectGraph();\n isConnected = true;\n };\n const whenDisconnected = () => {\n disconnectGraph();\n isConnected = false;\n };\n return monitorConnections(interceptConnections(nativeStereoPannerNodeFakerFactory, channelMergerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-factory.js\n\n\nconst createNativeWaveShaperNodeFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeWaveShaperNode = nativeContext.createWaveShaper();\n /*\n * Bug #119: Safari does not correctly map the values.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here. Testing for the automationRate property is necessary because this workaround\n * isn\'t necessary anymore since v14.0.2 of Safari.\n */\n if (nativeAudioContextConstructor !== null &&\n nativeAudioContextConstructor.name === \'webkitAudioContext\' &&\n nativeContext.createGain().gain.automationRate === undefined) {\n return createNativeWaveShaperNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativeWaveShaperNode, options);\n const curve = options.curve === null || options.curve instanceof Float32Array ? options.curve : new Float32Array(options.curve);\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (curve !== null && curve.length < 2) {\n throw createInvalidStateError();\n }\n // Only values of type Float32Array can be assigned to the curve property.\n assignNativeAudioNodeOption(nativeWaveShaperNode, { curve }, \'curve\');\n assignNativeAudioNodeOption(nativeWaveShaperNode, options, \'oversample\');\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n overwriteAccessors(nativeWaveShaperNode, \'curve\', (get) => () => get.call(nativeWaveShaperNode), (set) => (value) => {\n set.call(nativeWaveShaperNode, value);\n if (isConnected) {\n if (isDCCurve(value) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n else if (!isDCCurve(value) && disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n return value;\n });\n const whenConnected = () => {\n isConnected = true;\n if (isDCCurve(nativeWaveShaperNode.curve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n };\n const whenDisconnected = () => {\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(nativeWaveShaperNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-faker-factory.js\n\n\nconst createNativeWaveShaperNodeFakerFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections) => {\n return (nativeContext, { curve, oversample, ...audioNodeOptions }) => {\n const negativeWaveShaperNode = nativeContext.createWaveShaper();\n const positiveWaveShaperNode = nativeContext.createWaveShaper();\n assignNativeAudioNodeOptions(negativeWaveShaperNode, audioNodeOptions);\n assignNativeAudioNodeOptions(positiveWaveShaperNode, audioNodeOptions);\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const invertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n const outputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const revertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n let unmodifiedCurve = null;\n const nativeWaveShaperNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return negativeWaveShaperNode.channelCount;\n },\n set channelCount(value) {\n inputGainNode.channelCount = value;\n invertGainNode.channelCount = value;\n negativeWaveShaperNode.channelCount = value;\n outputGainNode.channelCount = value;\n positiveWaveShaperNode.channelCount = value;\n revertGainNode.channelCount = value;\n },\n get channelCountMode() {\n return negativeWaveShaperNode.channelCountMode;\n },\n set channelCountMode(value) {\n inputGainNode.channelCountMode = value;\n invertGainNode.channelCountMode = value;\n negativeWaveShaperNode.channelCountMode = value;\n outputGainNode.channelCountMode = value;\n positiveWaveShaperNode.channelCountMode = value;\n revertGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return negativeWaveShaperNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n invertGainNode.channelInterpretation = value;\n negativeWaveShaperNode.channelInterpretation = value;\n outputGainNode.channelInterpretation = value;\n positiveWaveShaperNode.channelInterpretation = value;\n revertGainNode.channelInterpretation = value;\n },\n get context() {\n return negativeWaveShaperNode.context;\n },\n get curve() {\n return unmodifiedCurve;\n },\n set curve(value) {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n if (value !== null && value.length < 2) {\n throw createInvalidStateError();\n }\n if (value === null) {\n negativeWaveShaperNode.curve = value;\n positiveWaveShaperNode.curve = value;\n }\n else {\n const curveLength = value.length;\n const negativeCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n const positiveCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n negativeCurve[0] = value[0];\n positiveCurve[0] = -value[curveLength - 1];\n const length = Math.ceil((curveLength + 1) / 2);\n const centerIndex = (curveLength + 1) / 2 - 1;\n for (let i = 1; i < length; i += 1) {\n const theoreticIndex = (i / length) * centerIndex;\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n negativeCurve[i] =\n lowerIndex === upperIndex\n ? value[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * value[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * value[upperIndex];\n positiveCurve[i] =\n lowerIndex === upperIndex\n ? -value[curveLength - 1 - lowerIndex]\n : -((1 - (theoreticIndex - lowerIndex)) * value[curveLength - 1 - lowerIndex]) -\n (1 - (upperIndex - theoreticIndex)) * value[curveLength - 1 - upperIndex];\n }\n negativeCurve[length] = curveLength % 2 === 1 ? value[length - 1] : (value[length - 2] + value[length - 1]) / 2;\n negativeWaveShaperNode.curve = negativeCurve;\n positiveWaveShaperNode.curve = positiveCurve;\n }\n unmodifiedCurve = value;\n if (isConnected) {\n if (isDCCurve(unmodifiedCurve) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n else if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return negativeWaveShaperNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return negativeWaveShaperNode.numberOfOutputs;\n },\n get oversample() {\n return negativeWaveShaperNode.oversample;\n },\n set oversample(value) {\n negativeWaveShaperNode.oversample = value;\n positiveWaveShaperNode.oversample = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (curve !== null) {\n // Only values of type Float32Array can be assigned to the curve property.\n nativeWaveShaperNodeFaker.curve = curve instanceof Float32Array ? curve : new Float32Array(curve);\n }\n if (oversample !== nativeWaveShaperNodeFaker.oversample) {\n nativeWaveShaperNodeFaker.oversample = oversample;\n }\n const whenConnected = () => {\n inputGainNode.connect(negativeWaveShaperNode).connect(outputGainNode);\n inputGainNode.connect(invertGainNode).connect(positiveWaveShaperNode).connect(revertGainNode).connect(outputGainNode);\n isConnected = true;\n if (isDCCurve(unmodifiedCurve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(negativeWaveShaperNode);\n negativeWaveShaperNode.disconnect(outputGainNode);\n inputGainNode.disconnect(invertGainNode);\n invertGainNode.disconnect(positiveWaveShaperNode);\n positiveWaveShaperNode.disconnect(revertGainNode);\n revertGainNode.disconnect(outputGainNode);\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(interceptConnections(nativeWaveShaperNodeFaker, outputGainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/not-supported-error.js\nconst createNotSupportedError = () => new DOMException(\'\', \'NotSupportedError\');\n//# sourceMappingURL=not-supported-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/offline-audio-context-constructor.js\n\n\nconst offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createOfflineAudioContextConstructor = (baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering) => {\n return class OfflineAudioContext extends baseAudioContextConstructor {\n constructor(a, b, c) {\n let options;\n if (typeof a === \'number\' && b !== undefined && c !== undefined) {\n options = { length: b, numberOfChannels: a, sampleRate: c };\n }\n else if (typeof a === \'object\') {\n options = a;\n }\n else {\n throw new Error(\'The given parameters are not valid.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-constructor.js\n\n\n\nconst oscillator_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 440,\n periodicWave: undefined,\n type: \'sine\'\n};\nconst createOscillatorNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class OscillatorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...oscillator_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOscillatorNode = createNativeOscillatorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const oscillatorNodeRenderer = (isOffline ? createOscillatorNodeRenderer() : null);\n const nyquist = context.sampleRate / 2;\n super(context, false, nativeOscillatorNode, oscillatorNodeRenderer);\n // Bug #81: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeOscillatorNode.detune, 153600, -153600);\n // Bug #76: Safari does not export the correct values for maxValue and minValue.\n this._frequency = createAudioParam(this, isOffline, nativeOscillatorNode.frequency, nyquist, -nyquist);\n this._nativeOscillatorNode = nativeOscillatorNode;\n this._onended = null;\n this._oscillatorNodeRenderer = oscillatorNodeRenderer;\n if (this._oscillatorNodeRenderer !== null && mergedOptions.periodicWave !== undefined) {\n this._oscillatorNodeRenderer.periodicWave =\n mergedOptions.periodicWave;\n }\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeOscillatorNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeOscillatorNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get type() {\n return this._nativeOscillatorNode.type;\n }\n set type(value) {\n this._nativeOscillatorNode.type = value;\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = null;\n }\n }\n setPeriodicWave(periodicWave) {\n this._nativeOscillatorNode.setPeriodicWave(periodicWave);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = periodicWave;\n }\n }\n start(when = 0) {\n this._nativeOscillatorNode.start(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeOscillatorNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeOscillatorNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeOscillatorNode.stop(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=oscillator-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-renderer-factory.js\n\nconst createOscillatorNodeRendererFactory = (connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeOscillatorNodes = new WeakMap();\n let periodicWave = null;\n let start = null;\n let stop = null;\n const createOscillatorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeOscillatorNode = getNativeAudioNode(proxy);\n // If the initially used nativeOscillatorNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeOscillatorNodeIsOwnedByContext = isOwnedByContext(nativeOscillatorNode, nativeOfflineAudioContext);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeOscillatorNode.channelCount,\n channelCountMode: nativeOscillatorNode.channelCountMode,\n channelInterpretation: nativeOscillatorNode.channelInterpretation,\n detune: nativeOscillatorNode.detune.value,\n frequency: nativeOscillatorNode.frequency.value,\n periodicWave: periodicWave === null ? undefined : periodicWave,\n type: nativeOscillatorNode.type\n };\n nativeOscillatorNode = createNativeOscillatorNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeOscillatorNode.start(start);\n }\n if (stop !== null) {\n nativeOscillatorNode.stop(stop);\n }\n }\n renderedNativeOscillatorNodes.set(nativeOfflineAudioContext, nativeOscillatorNode);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n return {\n set periodicWave(value) {\n periodicWave = value;\n },\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeOscillatorNode = renderedNativeOscillatorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeOscillatorNode !== undefined) {\n return Promise.resolve(renderedNativeOscillatorNode);\n }\n return createOscillatorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=oscillator-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-constructor.js\n\nconst panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: \'inverse\',\n maxDistance: 10000,\n orientationX: 1,\n orientationY: 0,\n orientationZ: 0,\n panningModel: \'equalpower\',\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1\n};\nconst createPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class PannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativePannerNode = createNativePannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const pannerNodeRenderer = (isOffline ? createPannerNodeRenderer() : null);\n super(context, false, nativePannerNode, pannerNodeRenderer);\n this._nativePannerNode = nativePannerNode;\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._orientationX = createAudioParam(this, isOffline, nativePannerNode.orientationX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationY = createAudioParam(this, isOffline, nativePannerNode.orientationY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationZ = createAudioParam(this, isOffline, nativePannerNode.orientationZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionX = createAudioParam(this, isOffline, nativePannerNode.positionX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionY = createAudioParam(this, isOffline, nativePannerNode.positionY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionZ = createAudioParam(this, isOffline, nativePannerNode.positionZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get coneInnerAngle() {\n return this._nativePannerNode.coneInnerAngle;\n }\n set coneInnerAngle(value) {\n this._nativePannerNode.coneInnerAngle = value;\n }\n get coneOuterAngle() {\n return this._nativePannerNode.coneOuterAngle;\n }\n set coneOuterAngle(value) {\n this._nativePannerNode.coneOuterAngle = value;\n }\n get coneOuterGain() {\n return this._nativePannerNode.coneOuterGain;\n }\n set coneOuterGain(value) {\n this._nativePannerNode.coneOuterGain = value;\n }\n get distanceModel() {\n return this._nativePannerNode.distanceModel;\n }\n set distanceModel(value) {\n this._nativePannerNode.distanceModel = value;\n }\n get maxDistance() {\n return this._nativePannerNode.maxDistance;\n }\n set maxDistance(value) {\n this._nativePannerNode.maxDistance = value;\n }\n get orientationX() {\n return this._orientationX;\n }\n get orientationY() {\n return this._orientationY;\n }\n get orientationZ() {\n return this._orientationZ;\n }\n get panningModel() {\n return this._nativePannerNode.panningModel;\n }\n set panningModel(value) {\n this._nativePannerNode.panningModel = value;\n }\n get positionX() {\n return this._positionX;\n }\n get positionY() {\n return this._positionY;\n }\n get positionZ() {\n return this._positionZ;\n }\n get refDistance() {\n return this._nativePannerNode.refDistance;\n }\n set refDistance(value) {\n this._nativePannerNode.refDistance = value;\n }\n get rolloffFactor() {\n return this._nativePannerNode.rolloffFactor;\n }\n set rolloffFactor(value) {\n this._nativePannerNode.rolloffFactor = value;\n }\n };\n};\n//# sourceMappingURL=panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-renderer-factory.js\n\n\nconst createPannerNodeRendererFactory = (connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n let renderedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = null;\n let nativePannerNode = getNativeAudioNode(proxy);\n const commonAudioNodeOptions = {\n channelCount: nativePannerNode.channelCount,\n channelCountMode: nativePannerNode.channelCountMode,\n channelInterpretation: nativePannerNode.channelInterpretation\n };\n const commonNativePannerNodeOptions = {\n ...commonAudioNodeOptions,\n coneInnerAngle: nativePannerNode.coneInnerAngle,\n coneOuterAngle: nativePannerNode.coneOuterAngle,\n coneOuterGain: nativePannerNode.coneOuterGain,\n distanceModel: nativePannerNode.distanceModel,\n maxDistance: nativePannerNode.maxDistance,\n panningModel: nativePannerNode.panningModel,\n refDistance: nativePannerNode.refDistance,\n rolloffFactor: nativePannerNode.rolloffFactor\n };\n // If the initially used nativePannerNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativePannerNodeIsOwnedByContext = isOwnedByContext(nativePannerNode, nativeOfflineAudioContext);\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (\'bufferSize\' in nativePannerNode) {\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n }\n else if (!nativePannerNodeIsOwnedByContext) {\n const options = {\n ...commonNativePannerNodeOptions,\n orientationX: nativePannerNode.orientationX.value,\n orientationY: nativePannerNode.orientationY.value,\n orientationZ: nativePannerNode.orientationZ.value,\n positionX: nativePannerNode.positionX.value,\n positionY: nativePannerNode.positionY.value,\n positionZ: nativePannerNode.positionZ.value\n };\n nativePannerNode = createNativePannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeGainNode === null ? nativePannerNode : nativeGainNode);\n if (nativeGainNode !== null) {\n if (renderedBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(6, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n const nativeChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n nativeChannelMergerNode.connect(partialOfflineAudioContext.destination);\n renderedBufferPromise = (async () => {\n const nativeConstantSourceNodes = await Promise.all([\n proxy.orientationX,\n proxy.orientationY,\n proxy.orientationZ,\n proxy.positionX,\n proxy.positionY,\n proxy.positionZ\n ].map(async (audioParam, index) => {\n const nativeConstantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: index === 0 ? 1 : 0\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, nativeConstantSourceNode.offset);\n return nativeConstantSourceNode;\n }));\n for (let i = 0; i < 6; i += 1) {\n nativeConstantSourceNodes[i].connect(nativeChannelMergerNode, 0, i);\n nativeConstantSourceNodes[i].start(0);\n }\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n })();\n }\n const renderedBuffer = await renderedBufferPromise;\n const inputGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, inputGainNode);\n const channelDatas = [];\n for (let i = 0; i < renderedBuffer.numberOfChannels; i += 1) {\n channelDatas.push(renderedBuffer.getChannelData(i));\n }\n let lastOrientation = [channelDatas[0][0], channelDatas[1][0], channelDatas[2][0]];\n let lastPosition = [channelDatas[3][0], channelDatas[4][0], channelDatas[5][0]];\n let gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n let partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n for (let i = 128; i < renderedBuffer.length; i += 128) {\n const orientation = [channelDatas[0][i], channelDatas[1][i], channelDatas[2][i]];\n const positon = [channelDatas[3][i], channelDatas[4][i], channelDatas[5][i]];\n if (orientation.some((value, index) => value !== lastOrientation[index]) ||\n positon.some((value, index) => value !== lastPosition[index])) {\n lastOrientation = orientation;\n lastPosition = positon;\n const currentTime = i / nativeOfflineAudioContext.sampleRate;\n gateGainNode.gain.setValueAtTime(0, currentTime);\n gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 0 });\n partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n gateGainNode.gain.setValueAtTime(1, currentTime);\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n }\n }\n return nativeGainNode;\n }\n if (!nativePannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n if (isNativeAudioNodeFaker(nativePannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode);\n }\n return nativePannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNodeOrNativePannerNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNodeOrNativePannerNode !== undefined) {\n return Promise.resolve(renderedNativeGainNodeOrNativePannerNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/periodic-wave-constructor.js\nconst periodic_wave_constructor_DEFAULT_OPTIONS = {\n disableNormalization: false\n};\nconst createPeriodicWaveConstructor = (createNativePeriodicWave, getNativeContext, periodicWaveStore, sanitizePeriodicWaveOptions) => {\n return class PeriodicWave {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizePeriodicWaveOptions({ ...periodic_wave_constructor_DEFAULT_OPTIONS, ...options });\n const periodicWave = createNativePeriodicWave(nativeContext, mergedOptions);\n periodicWaveStore.add(periodicWave);\n // This does violate all good pratices but it is used here to simplify the handling of periodic waves.\n return periodicWave;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === PeriodicWave.prototype) ||\n periodicWaveStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=periodic-wave-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-automation.js\nconst createRenderAutomation = (getAudioParamRenderer, renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n const audioParamRenderer = getAudioParamRenderer(audioParam);\n audioParamRenderer.replay(nativeAudioParam);\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=render-automation.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-node.js\nconst createRenderInputsOfAudioNode = (getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle) => {\n return async (audioNode, nativeOfflineAudioContext, nativeAudioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n await Promise.all(audioNodeConnections.activeInputs\n .map((connections, input) => Array.from(connections).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n const destination = audioNode.context.destination;\n if (!isPartOfACycle(source) && (audioNode !== destination || !isPartOfACycle(audioNode))) {\n renderedNativeAudioNode.connect(nativeAudioNode, output, input);\n }\n }))\n .reduce((allRenderingPromises, renderingPromises) => [...allRenderingPromises, ...renderingPromises], []));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-param.js\nconst createRenderInputsOfAudioParam = (getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle) => {\n return async (audioParam, nativeOfflineAudioContext, nativeAudioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n await Promise.all(Array.from(audioParamConnections.activeInputs).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n if (!isPartOfACycle(source)) {\n renderedNativeAudioNode.connect(nativeAudioParam, output);\n }\n }));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-native-offline-audio-context.js\n\nconst createRenderNativeOfflineAudioContext = (cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, testOfflineAudioContextCurrentTimeSupport) => {\n return (nativeOfflineAudioContext) => {\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n // Bug #158: Chrome and Edge do not advance currentTime if it is not accessed while rendering the audio.\n return Promise.resolve(cacheTestResult(testOfflineAudioContextCurrentTimeSupport, testOfflineAudioContextCurrentTimeSupport)).then((isOfflineAudioContextCurrentTimeSupported) => {\n if (!isOfflineAudioContextCurrentTimeSupported) {\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeOfflineAudioContext, 512, 0, 1);\n nativeOfflineAudioContext.oncomplete = () => {\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n scriptProcessorNode.disconnect();\n };\n scriptProcessorNode.onaudioprocess = () => nativeOfflineAudioContext.currentTime; // tslint:disable-line:deprecation\n scriptProcessorNode.connect(nativeOfflineAudioContext.destination);\n }\n return nativeOfflineAudioContext.startRendering();\n });\n }\n return new Promise((resolve) => {\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeOfflineAudioContext.oncomplete = (event) => {\n gainNode.disconnect();\n resolve(event.renderedBuffer);\n };\n gainNode.connect(nativeOfflineAudioContext.destination);\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=render-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-active-audio-worklet-node-inputs.js\nconst createSetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore) => {\n return (nativeAudioWorkletNode, activeInputs) => {\n activeAudioWorkletNodeInputsStore.set(nativeAudioWorkletNode, activeInputs);\n };\n};\n//# sourceMappingURL=set-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-audio-node-tail-time.js\nconst createSetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode, tailTime) => audioNodeTailTimeStore.set(audioNode, tailTime);\n};\n//# sourceMappingURL=set-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/start-rendering.js\n\nconst createStartRendering = (audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (destination, nativeOfflineAudioContext) => getAudioNodeRenderer(destination)\n .render(destination, nativeOfflineAudioContext)\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to the\n * destination.\n */\n .then(() => Promise.all(Array.from(getUnrenderedAudioWorkletNodes(nativeOfflineAudioContext)).map((audioWorkletNode) => getAudioNodeRenderer(audioWorkletNode).render(audioWorkletNode, nativeOfflineAudioContext))))\n .then(() => renderNativeOfflineAudioContext(nativeOfflineAudioContext))\n .then((audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n};\n//# sourceMappingURL=start-rendering.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-constructor.js\nconst stereo_panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n /*\n * Bug #105: The channelCountMode should be \'clamped-max\' according to the spec but is set to \'explicit\' to achieve consistent\n * behavior.\n */\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n pan: 0\n};\nconst createStereoPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext) => {\n return class StereoPannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...stereo_panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeStereoPannerNode = createNativeStereoPannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const stereoPannerNodeRenderer = (isOffline ? createStereoPannerNodeRenderer() : null);\n super(context, false, nativeStereoPannerNode, stereoPannerNodeRenderer);\n this._pan = createAudioParam(this, isOffline, nativeStereoPannerNode.pan);\n }\n get pan() {\n return this._pan;\n }\n };\n};\n//# sourceMappingURL=stereo-panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-renderer-factory.js\n\n\nconst createStereoPannerNodeRendererFactory = (connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeStereoPannerNodes = new WeakMap();\n const createStereoPannerNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeStereoPannerNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeStereoPannerNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeStereoPannerNodeIsOwnedByContext = isOwnedByContext(nativeStereoPannerNode, nativeOfflineAudioContext);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeStereoPannerNode.channelCount,\n channelCountMode: nativeStereoPannerNode.channelCountMode,\n channelInterpretation: nativeStereoPannerNode.channelInterpretation,\n pan: nativeStereoPannerNode.pan.value\n };\n nativeStereoPannerNode = createNativeStereoPannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeStereoPannerNodes.set(nativeOfflineAudioContext, nativeStereoPannerNode);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n if (isNativeAudioNodeFaker(nativeStereoPannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode);\n }\n return nativeStereoPannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeStereoPannerNode = renderedNativeStereoPannerNodes.get(nativeOfflineAudioContext);\n if (renderedNativeStereoPannerNode !== undefined) {\n return Promise.resolve(renderedNativeStereoPannerNode);\n }\n return createStereoPannerNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=stereo-panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-buffer-constructor-support.js\n// Bug #33: Safari exposes an AudioBuffer but it can\'t be used as a constructor.\nconst createTestAudioBufferConstructorSupport = (nativeAudioBufferConstructor) => {\n return () => {\n if (nativeAudioBufferConstructor === null) {\n return false;\n }\n try {\n new nativeAudioBufferConstructor({ length: 1, sampleRate: 44100 }); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n };\n};\n//# sourceMappingURL=test-audio-buffer-constructor-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-worklet-processor-post-message-support.js\n// Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\nconst createTestAudioWorkletProcessorPostMessageSupport = (nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor) => {\n return async () => {\n // Bug #61: If there is no native AudioWorkletNode it gets faked and therefore it is no problem if the it doesn\'t exist.\n if (nativeAudioWorkletNodeConstructor === null) {\n return true;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n return false;\n }\n const blob = new Blob([\'class A extends AudioWorkletProcessor{process(i){this.port.postMessage(i,[i[0][0].buffer])}}registerProcessor("a",A)\'], {\n type: \'application/javascript; charset=utf-8\'\n });\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n const offlineAudioContext = new nativeOfflineAudioContextConstructor(1, 128, 44100);\n const url = URL.createObjectURL(blob);\n let isEmittingMessageEvents = false;\n let isEmittingProcessorErrorEvents = false;\n try {\n await offlineAudioContext.audioWorklet.addModule(url);\n const audioWorkletNode = new nativeAudioWorkletNodeConstructor(offlineAudioContext, \'a\', { numberOfOutputs: 0 });\n const oscillator = offlineAudioContext.createOscillator();\n audioWorkletNode.port.onmessage = () => (isEmittingMessageEvents = true);\n audioWorkletNode.onprocessorerror = () => (isEmittingProcessorErrorEvents = true);\n oscillator.connect(audioWorkletNode);\n oscillator.start(0);\n await offlineAudioContext.startRendering();\n }\n catch {\n // Ignore errors.\n }\n finally {\n URL.revokeObjectURL(url);\n }\n return isEmittingMessageEvents && !isEmittingProcessorErrorEvents;\n };\n};\n//# sourceMappingURL=test-audio-worklet-processor-post-message-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-offline-audio-context-current-time-support.js\nconst createTestOfflineAudioContextCurrentTimeSupport = (createNativeGainNode, nativeOfflineAudioContextConstructor) => {\n return () => {\n if (nativeOfflineAudioContextConstructor === null) {\n return Promise.resolve(false);\n }\n const nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n // Bug #21: Safari does not support promises yet.\n return new Promise((resolve) => {\n nativeOfflineAudioContext.oncomplete = () => {\n gainNode.disconnect();\n resolve(nativeOfflineAudioContext.currentTime !== 0);\n };\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=test-offline-audio-context-current-time-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/unknown-error.js\nconst createUnknownError = () => new DOMException(\'\', \'UnknownError\');\n//# sourceMappingURL=unknown-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-constructor.js\nconst wave_shaper_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n curve: null,\n oversample: \'none\'\n};\nconst createWaveShaperNodeConstructor = (audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class WaveShaperNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...wave_shaper_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeWaveShaperNode = createNativeWaveShaperNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const waveShaperNodeRenderer = (isOffline ? createWaveShaperNodeRenderer() : null);\n // @todo Add a mechanism to only switch a WaveShaperNode to active while it is connected.\n super(context, true, nativeWaveShaperNode, waveShaperNodeRenderer);\n this._isCurveNullified = false;\n this._nativeWaveShaperNode = nativeWaveShaperNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get curve() {\n if (this._isCurveNullified) {\n return null;\n }\n return this._nativeWaveShaperNode.curve;\n }\n set curve(value) {\n // Bug #103: Safari does not allow to set the curve to null.\n if (value === null) {\n this._isCurveNullified = true;\n this._nativeWaveShaperNode.curve = new Float32Array([0, 0]);\n }\n else {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (value.length < 2) {\n throw createInvalidStateError();\n }\n this._isCurveNullified = false;\n this._nativeWaveShaperNode.curve = value;\n }\n }\n get oversample() {\n return this._nativeWaveShaperNode.oversample;\n }\n set oversample(value) {\n this._nativeWaveShaperNode.oversample = value;\n }\n };\n};\n//# sourceMappingURL=wave-shaper-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-renderer-factory.js\n\n\nconst createWaveShaperNodeRendererFactory = (createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeWaveShaperNodes = new WeakMap();\n const createWaveShaperNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeWaveShaperNode = getNativeAudioNode(proxy);\n // If the initially used nativeWaveShaperNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeWaveShaperNodeIsOwnedByContext = isOwnedByContext(nativeWaveShaperNode, nativeOfflineAudioContext);\n if (!nativeWaveShaperNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeWaveShaperNode.channelCount,\n channelCountMode: nativeWaveShaperNode.channelCountMode,\n channelInterpretation: nativeWaveShaperNode.channelInterpretation,\n curve: nativeWaveShaperNode.curve,\n oversample: nativeWaveShaperNode.oversample\n };\n nativeWaveShaperNode = createNativeWaveShaperNode(nativeOfflineAudioContext, options);\n }\n renderedNativeWaveShaperNodes.set(nativeOfflineAudioContext, nativeWaveShaperNode);\n if (isNativeAudioNodeFaker(nativeWaveShaperNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode);\n }\n return nativeWaveShaperNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeWaveShaperNode = renderedNativeWaveShaperNodes.get(nativeOfflineAudioContext);\n if (renderedNativeWaveShaperNode !== undefined) {\n return Promise.resolve(renderedNativeWaveShaperNode);\n }\n return createWaveShaperNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=wave-shaper-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/window.js\nconst createWindow = () => (typeof window === \'undefined\' ? null : window);\n//# sourceMappingURL=window.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods.js\nconst createWrapAudioBufferCopyChannelMethods = (convertNumberToUnsignedLong, createIndexSizeError) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const destinationLength = destination.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < destinationLength; i += 1) {\n destination[i] = channelData[i + bufferOffset];\n }\n };\n audioBuffer.copyToChannel = (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const sourceLength = source.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < sourceLength; i += 1) {\n channelData[i + bufferOffset] = source[i];\n }\n };\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods-out-of-bounds.js\nconst createWrapAudioBufferCopyChannelMethodsOutOfBounds = (convertNumberToUnsignedLong) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = ((copyFromChannel) => {\n return (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyFromChannel.call(audioBuffer, destination, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyFromChannel);\n audioBuffer.copyToChannel = ((copyToChannel) => {\n return (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyToChannel.call(audioBuffer, source, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyToChannel);\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods-out-of-bounds.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-source-node-stop-method-nullified-buffer.js\nconst createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer = (overwriteAccessors) => {\n return (nativeAudioBufferSourceNode, nativeContext) => {\n const nullifiedBuffer = nativeContext.createBuffer(1, 1, 44100);\n if (nativeAudioBufferSourceNode.buffer === null) {\n nativeAudioBufferSourceNode.buffer = nullifiedBuffer;\n }\n overwriteAccessors(nativeAudioBufferSourceNode, \'buffer\', (get) => () => {\n const value = get.call(nativeAudioBufferSourceNode);\n return value === nullifiedBuffer ? null : value;\n }, (set) => (value) => {\n return set.call(nativeAudioBufferSourceNode, value === null ? nullifiedBuffer : value);\n });\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-stop-method-nullified-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-channel-merger-node.js\nconst createWrapChannelMergerNode = (createInvalidStateError, monitorConnections) => {\n return (nativeContext, channelMergerNode) => {\n // Bug #15: Safari does not return the default properties.\n channelMergerNode.channelCount = 1;\n channelMergerNode.channelCountMode = \'explicit\';\n // Bug #16: Safari does not throw an error when setting a different channelCount or channelCountMode.\n Object.defineProperty(channelMergerNode, \'channelCount\', {\n get: () => 1,\n set: () => {\n throw createInvalidStateError();\n }\n });\n Object.defineProperty(channelMergerNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n });\n // Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n const audioBufferSourceNode = nativeContext.createBufferSource();\n const whenConnected = () => {\n const length = channelMergerNode.numberOfInputs;\n for (let i = 0; i < length; i += 1) {\n audioBufferSourceNode.connect(channelMergerNode, 0, i);\n }\n };\n const whenDisconnected = () => audioBufferSourceNode.disconnect(channelMergerNode);\n monitorConnections(channelMergerNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=wrap-channel-merger-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-first-sample.js\nconst getFirstSample = (audioBuffer, buffer, channelNumber) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n if (audioBuffer.copyFromChannel === undefined) {\n return audioBuffer.getChannelData(channelNumber)[0];\n }\n audioBuffer.copyFromChannel(buffer, channelNumber);\n return buffer[0];\n};\n//# sourceMappingURL=get-first-sample.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-dc-curve.js\nconst isDCCurve = (curve) => {\n if (curve === null) {\n return false;\n }\n const length = curve.length;\n if (length % 2 !== 0) {\n return curve[Math.floor(length / 2)] !== 0;\n }\n return curve[length / 2 - 1] + curve[length / 2] !== 0;\n};\n//# sourceMappingURL=is-dc-curve.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/overwrite-accessors.js\nconst overwriteAccessors = (object, property, createGetter, createSetter) => {\n let prototype = object;\n while (!prototype.hasOwnProperty(property)) {\n prototype = Object.getPrototypeOf(prototype);\n }\n const { get, set } = Object.getOwnPropertyDescriptor(prototype, property);\n Object.defineProperty(object, property, { get: createGetter(get), set: createSetter(set) });\n};\n//# sourceMappingURL=overwrite-accessors.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-audio-worklet-node-options.js\nconst sanitizeAudioWorkletNodeOptions = (options) => {\n return {\n ...options,\n outputChannelCount: options.outputChannelCount !== undefined\n ? options.outputChannelCount\n : options.numberOfInputs === 1 && options.numberOfOutputs === 1\n ? /*\n * Bug #61: This should be the computedNumberOfChannels, but unfortunately that is almost impossible to fake. That\'s why\n * the channelCountMode is required to be \'explicit\' as long as there is not a native implementation in every browser. That\n * makes sure the computedNumberOfChannels is equivilant to the channelCount which makes it much easier to compute.\n */\n [options.channelCount]\n : Array.from({ length: options.numberOfOutputs }, () => 1)\n };\n};\n//# sourceMappingURL=sanitize-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-channel-splitter-options.js\nconst sanitizeChannelSplitterOptions = (options) => {\n return { ...options, channelCount: options.numberOfOutputs };\n};\n//# sourceMappingURL=sanitize-channel-splitter-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-periodic-wave-options.js\nconst sanitizePeriodicWaveOptions = (options) => {\n const { imag, real } = options;\n if (imag === undefined) {\n if (real === undefined) {\n return { ...options, imag: [0, 0], real: [0, 0] };\n }\n return { ...options, imag: Array.from(real, () => 0), real };\n }\n if (real === undefined) {\n return { ...options, imag, real: Array.from(imag, () => 0) };\n }\n return { ...options, imag, real };\n};\n//# sourceMappingURL=sanitize-periodic-wave-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-value-at-time-until-possible.js\nconst setValueAtTimeUntilPossible = (audioParam, value, startTime) => {\n try {\n audioParam.setValueAtTime(value, startTime);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n setValueAtTimeUntilPossible(audioParam, value, startTime + 1e-7);\n }\n};\n//# sourceMappingURL=set-value-at-time-until-possible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-consecutive-calls-support.js\nconst testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.start();\n }\n catch {\n return true;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-offset-clamping-support.js\nconst testAudioBufferSourceNodeStartMethodOffsetClampingSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n try {\n nativeAudioBufferSourceNode.start(0, 1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-offset-clamping-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-stop-method-nullified-buffer-support.js\nconst testAudioBufferSourceNodeStopMethodNullifiedBufferSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.stop();\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-stop-method-nullified-buffer-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-start-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStartMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.start(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-start-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js\nconst testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.start();\n nativeAudioBufferSourceNode.stop();\n try {\n nativeAudioBufferSourceNode.stop();\n return true;\n }\n catch {\n return false;\n }\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStopMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.stop(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-worklet-node-options-clonability.js\nconst testAudioWorkletNodeOptionsClonability = (audioWorkletNodeOptions) => {\n const { port1, port2 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n port2.close();\n }\n};\n//# sourceMappingURL=test-audio-worklet-node-options-clonability.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-offset-clamping.js\nconst wrapAudioBufferSourceNodeStartMethodOffsetClamping = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n const buffer = nativeAudioBufferSourceNode.buffer;\n // Bug #154: Safari does not clamp the offset if it is equal to or greater than the duration of the buffer.\n const clampedOffset = buffer === null ? offset : Math.min(buffer.duration, offset);\n // Bug #155: Safari does not handle the offset correctly if it would cause the buffer to be not be played at all.\n if (buffer !== null && clampedOffset > buffer.duration - 0.5 / nativeAudioBufferSourceNode.context.sampleRate) {\n start.call(nativeAudioBufferSourceNode, when, 0, 0);\n }\n else {\n start.call(nativeAudioBufferSourceNode, when, clampedOffset, duration);\n }\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-offset-clamping.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js\n\nconst wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls = (nativeAudioScheduledSourceNode, nativeContext) => {\n const nativeGainNode = nativeContext.createGain();\n nativeAudioScheduledSourceNode.connect(nativeGainNode);\n const disconnectGainNode = ((disconnect) => {\n return () => {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnectGainNode);\n };\n })(nativeAudioScheduledSourceNode.disconnect);\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnectGainNode);\n interceptConnections(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n let isStopped = false;\n return (when = 0) => {\n if (isStopped) {\n try {\n stop.call(nativeAudioScheduledSourceNode, when);\n }\n catch {\n nativeGainNode.gain.setValueAtTime(0, when);\n }\n }\n else {\n stop.call(nativeAudioScheduledSourceNode, when);\n isStopped = true;\n }\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-event-listener.js\nconst wrapEventListener = (target, eventListener) => {\n return (event) => {\n const descriptor = { value: target };\n Object.defineProperties(event, {\n currentTarget: descriptor,\n target: descriptor\n });\n if (typeof eventListener === \'function\') {\n return eventListener.call(target, event);\n }\n return eventListener.handleEvent.call(target, event);\n };\n};\n//# sourceMappingURL=wrap-event-listener.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/module.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/*\n * @todo Explicitly referencing the barrel file seems to be necessary when enabling the\n * isolatedModules compiler option.\n */\n\n\nconst addActiveInputConnectionToAudioNode = createAddActiveInputConnectionToAudioNode(insertElementInSet);\nconst addPassiveInputConnectionToAudioNode = createAddPassiveInputConnectionToAudioNode(insertElementInSet);\nconst deleteActiveInputConnectionToAudioNode = createDeleteActiveInputConnectionToAudioNode(pickElementFromSet);\nconst audioNodeTailTimeStore = new WeakMap();\nconst getAudioNodeTailTime = createGetAudioNodeTailTime(audioNodeTailTimeStore);\nconst cacheTestResult = createCacheTestResult(new Map(), new WeakMap());\nconst module_window = createWindow();\nconst createNativeAnalyserNode = createNativeAnalyserNodeFactory(cacheTestResult, createIndexSizeError);\nconst getAudioNodeRenderer = createGetAudioNodeRenderer(getAudioNodeConnections);\nconst renderInputsOfAudioNode = createRenderInputsOfAudioNode(getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle);\nconst createAnalyserNodeRenderer = createAnalyserNodeRendererFactory(createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst getNativeContext = createGetNativeContext(CONTEXT_STORE);\nconst nativeOfflineAudioContextConstructor = createNativeOfflineAudioContextConstructor(module_window);\nconst isNativeOfflineAudioContext = createIsNativeOfflineAudioContext(nativeOfflineAudioContextConstructor);\nconst audioParamAudioNodeStore = new WeakMap();\nconst eventTargetConstructor = createEventTargetConstructor(wrapEventListener);\nconst nativeAudioContextConstructor = createNativeAudioContextConstructor(module_window);\nconst isNativeAudioContext = createIsNativeAudioContext(nativeAudioContextConstructor);\nconst module_isNativeAudioNode = createIsNativeAudioNode(module_window);\nconst isNativeAudioParam = createIsNativeAudioParam(module_window);\nconst nativeAudioWorkletNodeConstructor = createNativeAudioWorkletNodeConstructor(module_window);\nconst audioNodeConstructor = createAudioNodeConstructor(createAddAudioNodeConnections(AUDIO_NODE_CONNECTIONS_STORE), createAddConnectionToAudioNode(addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode), cacheTestResult, createIncrementCycleCounterFactory(CYCLE_COUNTERS, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode), createIndexSizeError, createInvalidAccessError, createNotSupportedError, createDecrementCycleCounter(connectNativeAudioNodeToNativeAudioNode, CYCLE_COUNTERS, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext), createDetectCycles(audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey), eventTargetConstructor, getNativeContext, isNativeAudioContext, module_isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor);\nconst analyserNodeConstructor = createAnalyserNodeConstructor(audioNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext);\n\nconst audioBufferStore = new WeakSet();\nconst nativeAudioBufferConstructor = createNativeAudioBufferConstructor(module_window);\nconst convertNumberToUnsignedLong = createConvertNumberToUnsignedLong(new Uint32Array(1));\nconst wrapAudioBufferCopyChannelMethods = createWrapAudioBufferCopyChannelMethods(convertNumberToUnsignedLong, createIndexSizeError);\nconst wrapAudioBufferCopyChannelMethodsOutOfBounds = createWrapAudioBufferCopyChannelMethodsOutOfBounds(convertNumberToUnsignedLong);\nconst audioBufferConstructor = createAudioBufferConstructor(audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, createTestAudioBufferConstructorSupport(nativeAudioBufferConstructor), wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\n\nconst addSilentConnection = createAddSilentConnection(createNativeGainNode);\nconst renderInputsOfAudioParam = createRenderInputsOfAudioParam(getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle);\nconst connectAudioParam = createConnectAudioParam(renderInputsOfAudioParam);\nconst createNativeAudioBufferSourceNode = createNativeAudioBufferSourceNodeFactory(addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClamping, createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer(overwriteAccessors), wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst renderAutomation = createRenderAutomation(createGetAudioParamRenderer(getAudioParamConnections), renderInputsOfAudioParam);\nconst createAudioBufferSourceNodeRenderer = createAudioBufferSourceNodeRendererFactory(connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst createAudioParam = createAudioParamFactory(createAddAudioParamConnections(AUDIO_PARAM_CONNECTIONS_STORE), audioParamAudioNodeStore, AUDIO_PARAM_STORE, createAudioParamRenderer, bundle.createCancelAndHoldAutomationEvent, bundle.createCancelScheduledValuesAutomationEvent, bundle.createExponentialRampToValueAutomationEvent, bundle.createLinearRampToValueAutomationEvent, bundle.createSetTargetAutomationEvent, bundle.createSetValueAutomationEvent, bundle.createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible);\nconst audioBufferSourceNodeConstructor = createAudioBufferSourceNodeConstructor(audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\n\nconst audioDestinationNodeConstructor = createAudioDestinationNodeConstructor(audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNodeFactory(createNativeGainNode, overwriteAccessors), getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode);\nconst createBiquadFilterNodeRenderer = createBiquadFilterNodeRendererFactory(connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst setAudioNodeTailTime = createSetAudioNodeTailTime(audioNodeTailTimeStore);\nconst biquadFilterNodeConstructor = createBiquadFilterNodeConstructor(audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst monitorConnections = createMonitorConnections(insertElementInSet, module_isNativeAudioNode);\nconst wrapChannelMergerNode = createWrapChannelMergerNode(createInvalidStateError, monitorConnections);\nconst createNativeChannelMergerNode = createNativeChannelMergerNodeFactory(nativeAudioContextConstructor, wrapChannelMergerNode);\nconst createChannelMergerNodeRenderer = createChannelMergerNodeRendererFactory(createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelMergerNodeConstructor = createChannelMergerNodeConstructor(audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext);\nconst createChannelSplitterNodeRenderer = createChannelSplitterNodeRendererFactory(createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelSplitterNodeConstructor = createChannelSplitterNodeConstructor(audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions);\nconst createNativeConstantSourceNodeFaker = createNativeConstantSourceNodeFakerFactory(addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections);\nconst createNativeConstantSourceNode = createNativeConstantSourceNodeFactory(addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport);\nconst createConstantSourceNodeRenderer = createConstantSourceNodeRendererFactory(connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst constantSourceNodeConstructor = createConstantSourceNodeConstructor(audioNodeConstructor, createAudioParam, createConstantSourceNodeRenderer, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createNativeConvolverNode = createNativeConvolverNodeFactory(createNotSupportedError, overwriteAccessors);\nconst createConvolverNodeRenderer = createConvolverNodeRendererFactory(createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst convolverNodeConstructor = createConvolverNodeConstructor(audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createDelayNodeRenderer = createDelayNodeRendererFactory(connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst delayNodeConstructor = createDelayNodeConstructor(audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativeDynamicsCompressorNode = createNativeDynamicsCompressorNodeFactory(createNotSupportedError);\nconst createDynamicsCompressorNodeRenderer = createDynamicsCompressorNodeRendererFactory(connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst dynamicsCompressorNodeConstructor = createDynamicsCompressorNodeConstructor(audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createGainNodeRenderer = createGainNodeRendererFactory(connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst gainNodeConstructor = createGainNodeConstructor(audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeIIRFilterNodeFaker = createNativeIIRFilterNodeFakerFactory(createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError);\nconst renderNativeOfflineAudioContext = createRenderNativeOfflineAudioContext(cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, createTestOfflineAudioContextCurrentTimeSupport(createNativeGainNode, nativeOfflineAudioContextConstructor));\nconst createIIRFilterNodeRenderer = createIIRFilterNodeRendererFactory(createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst createNativeIIRFilterNode = createNativeIIRFilterNodeFactory(createNativeIIRFilterNodeFaker);\nconst iIRFilterNodeConstructor = createIIRFilterNodeConstructor(audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createAudioListener = createAudioListenerFactory(createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors);\nconst unrenderedAudioWorkletNodeStore = new WeakMap();\nconst minimalBaseAudioContextConstructor = createMinimalBaseAudioContextConstructor(audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener);\nconst createNativeOscillatorNode = createNativeOscillatorNodeFactory(addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst createOscillatorNodeRenderer = createOscillatorNodeRendererFactory(connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst oscillatorNodeConstructor = createOscillatorNodeConstructor(audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createConnectedNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNodeFactory(createNativeAudioBufferSourceNode);\nconst createNativeWaveShaperNodeFaker = createNativeWaveShaperNodeFakerFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections);\nconst createNativeWaveShaperNode = createNativeWaveShaperNodeFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors);\nconst createNativePannerNodeFaker = createNativePannerNodeFakerFactory(connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections);\nconst createNativePannerNode = createNativePannerNodeFactory(createNativePannerNodeFaker);\nconst createPannerNodeRenderer = createPannerNodeRendererFactory(connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst pannerNodeConstructor = createPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativePeriodicWave = createNativePeriodicWaveFactory(createIndexSizeError);\nconst periodicWaveConstructor = createPeriodicWaveConstructor(createNativePeriodicWave, getNativeContext, new WeakSet(), sanitizePeriodicWaveOptions);\nconst nativeStereoPannerNodeFakerFactory = createNativeStereoPannerNodeFakerFactory(createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections);\nconst createNativeStereoPannerNode = createNativeStereoPannerNodeFactory(nativeStereoPannerNodeFakerFactory, createNotSupportedError);\nconst createStereoPannerNodeRenderer = createStereoPannerNodeRendererFactory(connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst stereoPannerNodeConstructor = createStereoPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext);\nconst createWaveShaperNodeRenderer = createWaveShaperNodeRendererFactory(createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst waveShaperNodeConstructor = createWaveShaperNodeConstructor(audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst isSecureContext = createIsSecureContext(module_window);\nconst exposeCurrentFrameAndCurrentTime = createExposeCurrentFrameAndCurrentTime(module_window);\nconst backupOfflineAudioContextStore = new WeakMap();\nconst getOrCreateBackupOfflineAudioContext = createGetOrCreateBackupOfflineAudioContext(backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor);\n// The addAudioWorkletModule() function is only available in a SecureContext.\nconst addAudioWorkletModule = isSecureContext\n ? createAddAudioWorkletModule(cacheTestResult, createNotSupportedError, createEvaluateSource(module_window), exposeCurrentFrameAndCurrentTime, createFetchSource(createAbortError), getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, new WeakMap(), new WeakMap(), createTestAudioWorkletProcessorPostMessageSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), \n // @todo window is guaranteed to be defined because isSecureContext checks that as well.\n module_window)\n : undefined;\nconst isNativeContext = createIsNativeContext(isNativeAudioContext, isNativeOfflineAudioContext);\nconst decodeAudioData = createDecodeAudioData(audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, new WeakSet(), getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst baseAudioContextConstructor = createBaseAudioContextConstructor(addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor);\nconst mediaElementAudioSourceNodeConstructor = createMediaElementAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioDestinationNodeConstructor = createMediaStreamAudioDestinationNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioSourceNodeConstructor = createMediaStreamAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNodeFactory(createInvalidStateError, isNativeOfflineAudioContext);\nconst mediaStreamTrackAudioSourceNodeConstructor = createMediaStreamTrackAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext);\nconst audioContextConstructor = createAudioContextConstructor(baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor);\n\nconst getUnrenderedAudioWorkletNodes = createGetUnrenderedAudioWorkletNodes(unrenderedAudioWorkletNodeStore);\nconst addUnrenderedAudioWorkletNode = createAddUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst connectMultipleOutputs = createConnectMultipleOutputs(createIndexSizeError);\nconst deleteUnrenderedAudioWorkletNode = createDeleteUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst disconnectMultipleOutputs = createDisconnectMultipleOutputs(createIndexSizeError);\nconst activeAudioWorkletNodeInputsStore = new WeakMap();\nconst getActiveAudioWorkletNodeInputs = createGetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore, getValueForKey);\nconst createNativeAudioWorkletNodeFaker = createNativeAudioWorkletNodeFakerFactory(connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections);\nconst createNativeAudioWorkletNode = createNativeAudioWorkletNodeFactory(createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections);\nconst createAudioWorkletNodeRenderer = createAudioWorkletNodeRendererFactory(connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst getBackupOfflineAudioContext = createGetBackupOfflineAudioContext(backupOfflineAudioContextStore);\nconst setActiveAudioWorkletNodeInputs = createSetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore);\n// The AudioWorkletNode constructor is only available in a SecureContext.\nconst audioWorkletNodeConstructor = isSecureContext\n ? createAudioWorkletNodeConstructor(addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener)\n : undefined;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst minimalAudioContextConstructor = createMinimalAudioContextConstructor(createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor);\n\nconst createNativeOfflineAudioContext = createCreateNativeOfflineAudioContext(createNotSupportedError, nativeOfflineAudioContextConstructor);\nconst startRendering = createStartRendering(audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst minimalOfflineAudioContextConstructor = createMinimalOfflineAudioContextConstructor(cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering);\n\nconst offlineAudioContextConstructor = createOfflineAudioContextConstructor(baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering);\n\n\n\n\n\n\nconst isAnyAudioContext = createIsAnyAudioContext(CONTEXT_STORE, isNativeAudioContext);\nconst isAnyAudioNode = createIsAnyAudioNode(AUDIO_NODE_STORE, module_isNativeAudioNode);\nconst isAnyAudioParam = createIsAnyAudioParam(AUDIO_PARAM_STORE, isNativeAudioParam);\nconst isAnyOfflineAudioContext = createIsAnyOfflineAudioContext(CONTEXT_STORE, isNativeOfflineAudioContext);\nconst isSupported = () => createIsSupportedPromise(cacheTestResult, createTestAudioBufferCopyChannelMethodsSubarraySupport(nativeOfflineAudioContextConstructor), createTestAudioContextCloseMethodSupport(nativeAudioContextConstructor), createTestAudioContextDecodeAudioDataMethodTypeErrorSupport(nativeOfflineAudioContextConstructor), createTestAudioContextOptionsSupport(nativeAudioContextConstructor), createTestAudioNodeConnectMethodSupport(nativeOfflineAudioContextConstructor), createTestAudioWorkletProcessorNoOutputsSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), createTestChannelMergerNodeChannelCountSupport(nativeOfflineAudioContextConstructor), createTestConstantSourceNodeAccurateSchedulingSupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeBufferReassignabilitySupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeChannelCountSupport(nativeOfflineAudioContextConstructor), testDomExceptionConstructorSupport, createTestIsSecureContextSupport(module_window), createTestMediaStreamAudioSourceNodeMediaStreamWithoutAudioTrackSupport(nativeAudioContextConstructor), createTestStereoPannerNodeDefaultValueSupport(nativeOfflineAudioContextConstructor), testTransferablesSupport);\n//# sourceMappingURL=module.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Debug.js\n/**\n * Assert that the statement is true, otherwise invoke the error.\n * @param statement\n * @param error The message which is passed into an Error\n */\nfunction Debug_assert(statement, error) {\n if (!statement) {\n throw new Error(error);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction Debug_assertRange(value, gte, lte = Infinity) {\n if (!(gte <= value && value <= lte)) {\n throw new RangeError(`Value must be within [${gte}, ${lte}], got: ${value}`);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction assertContextRunning(context) {\n // add a warning if the context is not started\n if (!context.isOffline && context.state !== "running") {\n Debug_warn("The AudioContext is \\"suspended\\". Invoke Tone.start() from a user action to start the audio.");\n }\n}\n/**\n * The default logger is the console\n */\nlet defaultLogger = console;\n/**\n * Set the logging interface\n */\nfunction setLogger(logger) {\n defaultLogger = logger;\n}\n/**\n * Log anything\n */\nfunction log(...args) {\n defaultLogger.log(...args);\n}\n/**\n * Warn anything\n */\nfunction Debug_warn(...args) {\n defaultLogger.warn(...args);\n}\n//# sourceMappingURL=Debug.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TypeCheck.js\n/**\n * Test if the arg is undefined\n */\nfunction TypeCheck_isUndef(arg) {\n return typeof arg === "undefined";\n}\n/**\n * Test if the arg is not undefined\n */\nfunction TypeCheck_isDefined(arg) {\n return !TypeCheck_isUndef(arg);\n}\n/**\n * Test if the arg is a function\n */\nfunction isFunction(arg) {\n return typeof arg === "function";\n}\n/**\n * Test if the argument is a number.\n */\nfunction TypeCheck_isNumber(arg) {\n return (typeof arg === "number");\n}\n/**\n * Test if the given argument is an object literal (i.e. `{}`);\n */\nfunction TypeCheck_isObject(arg) {\n return (Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object);\n}\n/**\n * Test if the argument is a boolean.\n */\nfunction TypeCheck_isBoolean(arg) {\n return (typeof arg === "boolean");\n}\n/**\n * Test if the argument is an Array\n */\nfunction TypeCheck_isArray(arg) {\n return (Array.isArray(arg));\n}\n/**\n * Test if the argument is a string.\n */\nfunction TypeCheck_isString(arg) {\n return (typeof arg === "string");\n}\n/**\n * Test if the argument is in the form of a note in scientific pitch notation.\n * e.g. "C4"\n */\nfunction isNote(arg) {\n return TypeCheck_isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg);\n}\n//# sourceMappingURL=TypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/AudioContext.js\n\n\n\n/**\n * Create a new AudioContext\n */\nfunction createAudioContext(options) {\n return new audioContextConstructor(options);\n}\n/**\n * Create a new OfflineAudioContext\n */\nfunction createOfflineAudioContext(channels, length, sampleRate) {\n return new offlineAudioContextConstructor(channels, length, sampleRate);\n}\n/**\n * A reference to the window object\n * @hidden\n */\nconst AudioContext_theWindow = typeof self === "object" ? self : null;\n/**\n * If the browser has a window object which has an AudioContext\n * @hidden\n */\nconst hasAudioContext = AudioContext_theWindow &&\n (AudioContext_theWindow.hasOwnProperty("AudioContext") || AudioContext_theWindow.hasOwnProperty("webkitAudioContext"));\nfunction createAudioWorkletNode(context, name, options) {\n Debug_assert(TypeCheck_isDefined(audioWorkletNodeConstructor), "This node only works in a secure context (https or localhost)");\n // @ts-ignore\n return new audioWorkletNodeConstructor(context, name, options);\n}\n/**\n * This promise resolves to a boolean which indicates if the\n * functionality is supported within the currently used browse.\n * Taken from [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context#issupported)\n */\n\n//# sourceMappingURL=AudioContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== "function" && b !== null)\r\n throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }\r\n var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";\r\n var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === "accessor") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== "object") throw new TypeError("Object expected");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === "field") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nfunction __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nfunction __propKey(x) {\r\n return typeof x === "symbol" ? x : "".concat(x);\r\n};\r\n\r\nfunction __setFunctionName(f, name, prefix) {\r\n if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";\r\n return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });\r\n};\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction tslib_es6_awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError("Generator is already executing.");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === "number") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === "function" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i["return"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume("next", value); }\r\n function reject(value) { resume("throw", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, "default", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o["default"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");\r\n return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === "m") throw new TypeError("Private method is not writable");\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");\r\n return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nfunction __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use \'in\' operator on non-object");\r\n return typeof state === "function" ? receiver === state : state.has(receiver);\r\n}\r\n\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Ticker.js\n/**\n * A class which provides a reliable callback using either\n * a Web Worker, or if that isn\'t supported, falls back to setTimeout.\n */\nclass Ticker {\n constructor(callback, type, updateInterval) {\n this._callback = callback;\n this._type = type;\n this._updateInterval = updateInterval;\n // create the clock source for the first time\n this._createClock();\n }\n /**\n * Generate a web worker\n */\n _createWorker() {\n const blob = new Blob([\n /* javascript */ `\n\t\t\t// the initial timeout time\n\t\t\tlet timeoutTime = ${(this._updateInterval * 1000).toFixed(1)};\n\t\t\t// onmessage callback\n\t\t\tself.onmessage = function(msg){\n\t\t\t\ttimeoutTime = parseInt(msg.data);\n\t\t\t};\n\t\t\t// the tick function which posts a message\n\t\t\t// and schedules a new tick\n\t\t\tfunction tick(){\n\t\t\t\tsetTimeout(tick, timeoutTime);\n\t\t\t\tself.postMessage(\'tick\');\n\t\t\t}\n\t\t\t// call tick initially\n\t\t\ttick();\n\t\t\t`\n ], { type: "text/javascript" });\n const blobUrl = URL.createObjectURL(blob);\n const worker = new Worker(blobUrl);\n worker.onmessage = this._callback.bind(this);\n this._worker = worker;\n }\n /**\n * Create a timeout loop\n */\n _createTimeout() {\n this._timeout = setTimeout(() => {\n this._createTimeout();\n this._callback();\n }, this._updateInterval * 1000);\n }\n /**\n * Create the clock source.\n */\n _createClock() {\n if (this._type === "worker") {\n try {\n this._createWorker();\n }\n catch (e) {\n // workers not supported, fallback to timeout\n this._type = "timeout";\n this._createClock();\n }\n }\n else if (this._type === "timeout") {\n this._createTimeout();\n }\n }\n /**\n * Clean up the current clock source\n */\n _disposeClock() {\n if (this._timeout) {\n clearTimeout(this._timeout);\n this._timeout = 0;\n }\n if (this._worker) {\n this._worker.terminate();\n this._worker.onmessage = null;\n }\n }\n /**\n * The rate in seconds the ticker will update\n */\n get updateInterval() {\n return this._updateInterval;\n }\n set updateInterval(interval) {\n this._updateInterval = Math.max(interval, 128 / 44100);\n if (this._type === "worker") {\n this._worker.postMessage(Math.max(interval * 1000, 1));\n }\n }\n /**\n * The type of the ticker, either a worker or a timeout\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._disposeClock();\n this._type = type;\n this._createClock();\n }\n /**\n * Clean up\n */\n dispose() {\n this._disposeClock();\n }\n}\n//# sourceMappingURL=Ticker.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/AdvancedTypeCheck.js\n\n/**\n * Test if the given value is an instanceof AudioParam\n */\nfunction isAudioParam(arg) {\n return isAnyAudioParam(arg);\n}\n/**\n * Test if the given value is an instanceof AudioNode\n */\nfunction AdvancedTypeCheck_isAudioNode(arg) {\n return isAnyAudioNode(arg);\n}\n/**\n * Test if the arg is instanceof an OfflineAudioContext\n */\nfunction isOfflineAudioContext(arg) {\n return isAnyOfflineAudioContext(arg);\n}\n/**\n * Test if the arg is an instanceof AudioContext\n */\nfunction isAudioContext(arg) {\n return isAnyAudioContext(arg);\n}\n/**\n * Test if the arg is instanceof an AudioBuffer\n */\nfunction isAudioBuffer(arg) {\n return arg instanceof AudioBuffer;\n}\n//# sourceMappingURL=AdvancedTypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Defaults.js\n\n\n/**\n * Some objects should not be merged\n */\nfunction noCopy(key, arg) {\n return key === "value" || isAudioParam(arg) || AdvancedTypeCheck_isAudioNode(arg) || isAudioBuffer(arg);\n}\nfunction Defaults_deepMerge(target, ...sources) {\n if (!sources.length) {\n return target;\n }\n const source = sources.shift();\n if (TypeCheck_isObject(target) && TypeCheck_isObject(source)) {\n for (const key in source) {\n if (noCopy(key, source[key])) {\n target[key] = source[key];\n }\n else if (TypeCheck_isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} });\n }\n Defaults_deepMerge(target[key], source[key]);\n }\n else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n // @ts-ignore\n return Defaults_deepMerge(target, ...sources);\n}\n/**\n * Returns true if the two arrays have the same value for each of the elements\n */\nfunction deepEquals(arrayA, arrayB) {\n return arrayA.length === arrayB.length && arrayA.every((element, index) => arrayB[index] === element);\n}\n/**\n * Convert an args array into an object.\n */\nfunction Defaults_optionsFromArguments(defaults, argsArray, keys = [], objKey) {\n const opts = {};\n const args = Array.from(argsArray);\n // if the first argument is an object and has an object key\n if (TypeCheck_isObject(args[0]) && objKey && !Reflect.has(args[0], objKey)) {\n // if it\'s not part of the defaults\n const partOfDefaults = Object.keys(args[0]).some(key => Reflect.has(defaults, key));\n if (!partOfDefaults) {\n // merge that key\n Defaults_deepMerge(opts, { [objKey]: args[0] });\n // remove the obj key from the keys\n keys.splice(keys.indexOf(objKey), 1);\n // shift the first argument off\n args.shift();\n }\n }\n if (args.length === 1 && TypeCheck_isObject(args[0])) {\n Defaults_deepMerge(opts, args[0]);\n }\n else {\n for (let i = 0; i < keys.length; i++) {\n if (TypeCheck_isDefined(args[i])) {\n opts[keys[i]] = args[i];\n }\n }\n }\n return Defaults_deepMerge(defaults, opts);\n}\n/**\n * Return this instances default values by calling Constructor.getDefaults()\n */\nfunction getDefaultsFromInstance(instance) {\n return instance.constructor.getDefaults();\n}\n/**\n * Returns the fallback if the given object is undefined.\n * Take an array of arguments and return a formatted options object.\n */\nfunction Defaults_defaultArg(given, fallback) {\n if (TypeCheck_isUndef(given)) {\n return fallback;\n }\n else {\n return given;\n }\n}\n/**\n * Remove all of the properties belonging to omit from obj.\n */\nfunction Defaults_omitFromObject(obj, omit) {\n omit.forEach(prop => {\n if (Reflect.has(obj, prop)) {\n delete obj[prop];\n }\n });\n return obj;\n}\n//# sourceMappingURL=Defaults.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Tone.js\n/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2019 Yotam Mann\n */\n\n\n\n/**\n * @class Tone is the base class of all other classes.\n * @category Core\n * @constructor\n */\nclass Tone {\n constructor() {\n //-------------------------------------\n // \tDEBUGGING\n //-------------------------------------\n /**\n * Set this debug flag to log all events that happen in this class.\n */\n this.debug = false;\n //-------------------------------------\n // \tDISPOSING\n //-------------------------------------\n /**\n * Indicates if the instance was disposed\n */\n this._wasDisposed = false;\n }\n /**\n * Returns all of the default options belonging to the class.\n */\n static getDefaults() {\n return {};\n }\n /**\n * Prints the outputs to the console log for debugging purposes.\n * Prints the contents only if either the object has a property\n * called `debug` set to true, or a variable called TONE_DEBUG_CLASS\n * is set to the name of the class.\n * @example\n * const osc = new Tone.Oscillator();\n * // prints all logs originating from this oscillator\n * osc.debug = true;\n * // calls to start/stop will print in the console\n * osc.start();\n */\n log(...args) {\n // if the object is either set to debug = true\n // or if there is a string on the Tone.global.with the class name\n if (this.debug || (AudioContext_theWindow && this.toString() === AudioContext_theWindow.TONE_DEBUG_CLASS)) {\n log(this, ...args);\n }\n }\n /**\n * disconnect and dispose.\n */\n dispose() {\n this._wasDisposed = true;\n return this;\n }\n /**\n * Indicates if the instance was disposed. \'Disposing\' an\n * instance means that all of the Web Audio nodes that were\n * created for the instance are disconnected and freed for garbage collection.\n */\n get disposed() {\n return this._wasDisposed;\n }\n /**\n * Convert the class to a string\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.toString());\n */\n toString() {\n return this.name;\n }\n}\n/**\n * The version number semver\n */\nTone.version = version;\n//# sourceMappingURL=Tone.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Math.js\n/**\n * The threshold for correctness for operators. Less than one sample even\n * at very high sampling rates (e.g. `1e-6 < 1 / 192000`).\n */\nconst EPSILON = 1e-6;\n/**\n * Test if A is greater than B\n */\nfunction GT(a, b) {\n return a > b + EPSILON;\n}\n/**\n * Test if A is greater than or equal to B\n */\nfunction GTE(a, b) {\n return GT(a, b) || EQ(a, b);\n}\n/**\n * Test if A is less than B\n */\nfunction LT(a, b) {\n return a + EPSILON < b;\n}\n/**\n * Test if A is less than B\n */\nfunction EQ(a, b) {\n return Math.abs(a - b) < EPSILON;\n}\n/**\n * Clamp the value within the given range\n */\nfunction Math_clamp(value, min, max) {\n return Math.max(Math.min(value, max), min);\n}\n//# sourceMappingURL=Math.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Timeline.js\n\n\n\n\n/**\n * A Timeline class for scheduling and maintaining state\n * along a timeline. All events must have a "time" property.\n * Internally, events are stored in time order for fast\n * retrieval.\n */\nclass Timeline extends Tone {\n constructor() {\n super();\n this.name = "Timeline";\n /**\n * The array of scheduled timeline events\n */\n this._timeline = [];\n const options = Defaults_optionsFromArguments(Timeline.getDefaults(), arguments, ["memory"]);\n this.memory = options.memory;\n this.increasing = options.increasing;\n }\n static getDefaults() {\n return {\n memory: Infinity,\n increasing: false,\n };\n }\n /**\n * The number of items in the timeline.\n */\n get length() {\n return this._timeline.length;\n }\n /**\n * Insert an event object onto the timeline. Events must have a "time" attribute.\n * @param event The event object to insert into the timeline.\n */\n add(event) {\n // the event needs to have a time attribute\n Debug_assert(Reflect.has(event, "time"), "Timeline: events must have a time attribute");\n event.time = event.time.valueOf();\n if (this.increasing && this.length) {\n const lastValue = this._timeline[this.length - 1];\n Debug_assert(GTE(event.time, lastValue.time), "The time must be greater than or equal to the last scheduled time");\n this._timeline.push(event);\n }\n else {\n const index = this._search(event.time);\n this._timeline.splice(index + 1, 0, event);\n }\n // if the length is more than the memory, remove the previous ones\n if (this.length > this.memory) {\n const diff = this.length - this.memory;\n this._timeline.splice(0, diff);\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param {Object} event The event object to remove from the list.\n * @returns {Timeline} this\n */\n remove(event) {\n const index = this._timeline.indexOf(event);\n if (index !== -1) {\n this._timeline.splice(index, 1);\n }\n return this;\n }\n /**\n * Get the nearest event whose time is less than or equal to the given time.\n * @param time The time to query.\n */\n get(time, param = "time") {\n const index = this._search(time, param);\n if (index !== -1) {\n return this._timeline[index];\n }\n else {\n return null;\n }\n }\n /**\n * Return the first event in the timeline without removing it\n * @returns {Object} The first event object\n */\n peek() {\n return this._timeline[0];\n }\n /**\n * Return the first event in the timeline and remove it\n */\n shift() {\n return this._timeline.shift();\n }\n /**\n * Get the event which is scheduled after the given time.\n * @param time The time to query.\n */\n getAfter(time, param = "time") {\n const index = this._search(time, param);\n if (index + 1 < this._timeline.length) {\n return this._timeline[index + 1];\n }\n else {\n return null;\n }\n }\n /**\n * Get the event before the event at the given time.\n * @param time The time to query.\n */\n getBefore(time) {\n const len = this._timeline.length;\n // if it\'s after the last item, return the last item\n if (len > 0 && this._timeline[len - 1].time < time) {\n return this._timeline[len - 1];\n }\n const index = this._search(time);\n if (index - 1 >= 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Cancel events at and after the given time\n * @param after The time to query.\n */\n cancel(after) {\n if (this._timeline.length > 1) {\n let index = this._search(after);\n if (index >= 0) {\n if (EQ(this._timeline[index].time, after)) {\n // get the first item with that time\n for (let i = index; i >= 0; i--) {\n if (EQ(this._timeline[i].time, after)) {\n index = i;\n }\n else {\n break;\n }\n }\n this._timeline = this._timeline.slice(0, index);\n }\n else {\n this._timeline = this._timeline.slice(0, index + 1);\n }\n }\n else {\n this._timeline = [];\n }\n }\n else if (this._timeline.length === 1) {\n // the first item\'s time\n if (GTE(this._timeline[0].time, after)) {\n this._timeline = [];\n }\n }\n return this;\n }\n /**\n * Cancel events before or equal to the given time.\n * @param time The time to cancel before.\n */\n cancelBefore(time) {\n const index = this._search(time);\n if (index >= 0) {\n this._timeline = this._timeline.slice(index + 1);\n }\n return this;\n }\n /**\n * Returns the previous event if there is one. null otherwise\n * @param event The event to find the previous one of\n * @return The event right before the given event\n */\n previousEvent(event) {\n const index = this._timeline.indexOf(event);\n if (index > 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Does a binary search on the timeline array and returns the\n * nearest event index whose time is after or equal to the given time.\n * If a time is searched before the first index in the timeline, -1 is returned.\n * If the time is after the end, the index of the last item is returned.\n */\n _search(time, param = "time") {\n if (this._timeline.length === 0) {\n return -1;\n }\n let beginning = 0;\n const len = this._timeline.length;\n let end = len;\n if (len > 0 && this._timeline[len - 1][param] <= time) {\n return len - 1;\n }\n while (beginning < end) {\n // calculate the midpoint for roughly equal partition\n let midPoint = Math.floor(beginning + (end - beginning) / 2);\n const event = this._timeline[midPoint];\n const nextEvent = this._timeline[midPoint + 1];\n if (EQ(event[param], time)) {\n // choose the last one that has the same time\n for (let i = midPoint; i < this._timeline.length; i++) {\n const testEvent = this._timeline[i];\n if (EQ(testEvent[param], time)) {\n midPoint = i;\n }\n else {\n break;\n }\n }\n return midPoint;\n }\n else if (LT(event[param], time) && GT(nextEvent[param], time)) {\n return midPoint;\n }\n else if (GT(event[param], time)) {\n // search lower\n end = midPoint;\n }\n else {\n // search upper\n beginning = midPoint + 1;\n }\n }\n return -1;\n }\n /**\n * Internal iterator. Applies extra safety checks for\n * removing items from the array.\n */\n _iterate(callback, lowerBound = 0, upperBound = this._timeline.length - 1) {\n this._timeline.slice(lowerBound, upperBound + 1).forEach(callback);\n }\n /**\n * Iterate over everything in the array\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n this._iterate(callback);\n return this;\n }\n /**\n * Iterate over everything in the array at or before the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachBefore(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array after the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAfter(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const lowerBound = this._search(time);\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array between the startTime and endTime.\n * The timerange is inclusive of the startTime, but exclusive of the endTime.\n * range = [startTime, endTime).\n * @param startTime The time to check if items are before\n * @param endTime The end of the test interval.\n * @param callback The callback to invoke with every item\n */\n forEachBetween(startTime, endTime, callback) {\n let lowerBound = this._search(startTime);\n let upperBound = this._search(endTime);\n if (lowerBound !== -1 && upperBound !== -1) {\n if (this._timeline[lowerBound].time !== startTime) {\n lowerBound += 1;\n }\n // exclusive of the end time\n if (this._timeline[upperBound].time === endTime) {\n upperBound -= 1;\n }\n this._iterate(callback, lowerBound, upperBound);\n }\n else if (lowerBound === -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array at or after the given time. Similar to\n * forEachAfter, but includes the item(s) at the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n let lowerBound = this._search(time);\n // work backwards until the event time is less than time\n while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) {\n lowerBound--;\n }\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array at the given time\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1 && EQ(this._timeline[upperBound].time, time)) {\n let lowerBound = upperBound;\n for (let i = upperBound; i >= 0; i--) {\n if (EQ(this._timeline[i].time, time)) {\n lowerBound = i;\n }\n else {\n break;\n }\n }\n this._iterate(event => {\n callback(event);\n }, lowerBound, upperBound);\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._timeline = [];\n return this;\n }\n}\n//# sourceMappingURL=Timeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ContextInitialization.js\n//-------------------------------------\n// INITIALIZING NEW CONTEXT\n//-------------------------------------\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyNewContext = [];\n/**\n * Used internally to setup a new Context\n */\nfunction onContextInit(cb) {\n notifyNewContext.push(cb);\n}\n/**\n * Invoke any classes which need to also be initialized when a new context is created.\n */\nfunction initializeContext(ctx) {\n // add any additional modules\n notifyNewContext.forEach(cb => cb(ctx));\n}\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyCloseContext = [];\n/**\n * Used internally to tear down a Context\n */\nfunction onContextClose(cb) {\n notifyCloseContext.push(cb);\n}\nfunction closeContext(ctx) {\n // add any additional modules\n notifyCloseContext.forEach(cb => cb(ctx));\n}\n//# sourceMappingURL=ContextInitialization.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Emitter.js\n\n\n/**\n * Emitter gives classes which extend it\n * the ability to listen for and emit events.\n * Inspiration and reference from Jerome Etienne\'s [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n * MIT (c) 2011 Jerome Etienne.\n * @category Core\n */\nclass Emitter extends Tone {\n constructor() {\n super(...arguments);\n this.name = "Emitter";\n }\n /**\n * Bind a callback to a specific event.\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n on(event, callback) {\n // split the event\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (!this._events.hasOwnProperty(eventName)) {\n this._events[eventName] = [];\n }\n this._events[eventName].push(callback);\n });\n return this;\n }\n /**\n * Bind a callback which is only invoked once\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n once(event, callback) {\n const boundCallback = (...args) => {\n // invoke the callback\n callback(...args);\n // remove the event\n this.off(event, boundCallback);\n };\n this.on(event, boundCallback);\n return this;\n }\n /**\n * Remove the event listener.\n * @param event The event to stop listening to.\n * @param callback The callback which was bound to the event with Emitter.on.\n * If no callback is given, all callbacks events are removed.\n */\n off(event, callback) {\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (this._events.hasOwnProperty(event)) {\n if (TypeCheck_isUndef(callback)) {\n this._events[event] = [];\n }\n else {\n const eventList = this._events[event];\n for (let i = eventList.length - 1; i >= 0; i--) {\n if (eventList[i] === callback) {\n eventList.splice(i, 1);\n }\n }\n }\n }\n });\n return this;\n }\n /**\n * Invoke all of the callbacks bound to the event\n * with any arguments passed in.\n * @param event The name of the event.\n * @param args The arguments to pass to the functions listening.\n */\n emit(event, ...args) {\n if (this._events) {\n if (this._events.hasOwnProperty(event)) {\n const eventList = this._events[event].slice(0);\n for (let i = 0, len = eventList.length; i < len; i++) {\n eventList[i].apply(this, args);\n }\n }\n }\n return this;\n }\n /**\n * Add Emitter functions (on/off/emit) to the object\n */\n static mixin(constr) {\n // instance._events = {};\n ["on", "once", "off", "emit"].forEach(name => {\n const property = Object.getOwnPropertyDescriptor(Emitter.prototype, name);\n Object.defineProperty(constr.prototype, name, property);\n });\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._events = undefined;\n return this;\n }\n}\n//# sourceMappingURL=Emitter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/BaseContext.js\n\nclass BaseContext extends Emitter {\n constructor() {\n super(...arguments);\n this.isOffline = false;\n }\n /*\n * This is a placeholder so that JSON.stringify does not throw an error\n * This matches what JSON.stringify(audioContext) returns on a native\n * audioContext instance.\n */\n toJSON() {\n return {};\n }\n}\n//# sourceMappingURL=BaseContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Context.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native AudioContext.\n * @category Core\n */\nclass Context extends BaseContext {\n constructor() {\n super();\n this.name = "Context";\n /**\n * An object containing all of the constants AudioBufferSourceNodes\n */\n this._constants = new Map();\n /**\n * All of the setTimeout events.\n */\n this._timeouts = new Timeline();\n /**\n * The timeout id counter\n */\n this._timeoutIds = 0;\n /**\n * Private indicator if the context has been initialized\n */\n this._initialized = false;\n /**\n * Indicates if the context is an OfflineAudioContext or an AudioContext\n */\n this.isOffline = false;\n //--------------------------------------------\n // AUDIO WORKLET\n //--------------------------------------------\n /**\n * Maps a module name to promise of the addModule method\n */\n this._workletModules = new Map();\n const options = Defaults_optionsFromArguments(Context.getDefaults(), arguments, [\n "context",\n ]);\n if (options.context) {\n this._context = options.context;\n }\n else {\n this._context = createAudioContext({\n latencyHint: options.latencyHint,\n });\n }\n this._ticker = new Ticker(this.emit.bind(this, "tick"), options.clockSource, options.updateInterval);\n this.on("tick", this._timeoutLoop.bind(this));\n // fwd events from the context\n this._context.onstatechange = () => {\n this.emit("statechange", this.state);\n };\n this._setLatencyHint(options.latencyHint);\n this.lookAhead = options.lookAhead;\n }\n static getDefaults() {\n return {\n clockSource: "worker",\n latencyHint: "interactive",\n lookAhead: 0.1,\n updateInterval: 0.05,\n };\n }\n /**\n * Finish setting up the context. **You usually do not need to do this manually.**\n */\n initialize() {\n if (!this._initialized) {\n // add any additional modules\n initializeContext(this);\n this._initialized = true;\n }\n return this;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return this._context.createAnalyser();\n }\n createOscillator() {\n return this._context.createOscillator();\n }\n createBufferSource() {\n return this._context.createBufferSource();\n }\n createBiquadFilter() {\n return this._context.createBiquadFilter();\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return this._context.createBuffer(numberOfChannels, length, sampleRate);\n }\n createChannelMerger(numberOfInputs) {\n return this._context.createChannelMerger(numberOfInputs);\n }\n createChannelSplitter(numberOfOutputs) {\n return this._context.createChannelSplitter(numberOfOutputs);\n }\n createConstantSource() {\n return this._context.createConstantSource();\n }\n createConvolver() {\n return this._context.createConvolver();\n }\n createDelay(maxDelayTime) {\n return this._context.createDelay(maxDelayTime);\n }\n createDynamicsCompressor() {\n return this._context.createDynamicsCompressor();\n }\n createGain() {\n return this._context.createGain();\n }\n createIIRFilter(feedForward, feedback) {\n // @ts-ignore\n return this._context.createIIRFilter(feedForward, feedback);\n }\n createPanner() {\n return this._context.createPanner();\n }\n createPeriodicWave(real, imag, constraints) {\n return this._context.createPeriodicWave(real, imag, constraints);\n }\n createStereoPanner() {\n return this._context.createStereoPanner();\n }\n createWaveShaper() {\n return this._context.createWaveShaper();\n }\n createMediaStreamSource(stream) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamSource(stream);\n }\n createMediaElementSource(element) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaElementSource(element);\n }\n createMediaStreamDestination() {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamDestination();\n }\n decodeAudioData(audioData) {\n return this._context.decodeAudioData(audioData);\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get currentTime() {\n return this._context.currentTime;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get state() {\n return this._context.state;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get sampleRate() {\n return this._context.sampleRate;\n }\n /**\n * The listener\n */\n get listener() {\n this.initialize();\n return this._listener;\n }\n set listener(l) {\n Debug_assert(!this._initialized, "The listener cannot be set after initialization.");\n this._listener = l;\n }\n /**\n * There is only one Transport per Context. It is created on initialization.\n */\n get transport() {\n this.initialize();\n return this._transport;\n }\n set transport(t) {\n Debug_assert(!this._initialized, "The transport cannot be set after initialization.");\n this._transport = t;\n }\n /**\n * This is the Draw object for the context which is useful for synchronizing the draw frame with the Tone.js clock.\n */\n get draw() {\n this.initialize();\n return this._draw;\n }\n set draw(d) {\n Debug_assert(!this._initialized, "Draw cannot be set after initialization.");\n this._draw = d;\n }\n /**\n * A reference to the Context\'s destination node.\n */\n get destination() {\n this.initialize();\n return this._destination;\n }\n set destination(d) {\n Debug_assert(!this._initialized, "The destination cannot be set after initialization.");\n this._destination = d;\n }\n /**\n * Create an audio worklet node from a name and options. The module\n * must first be loaded using [[addAudioWorkletModule]].\n */\n createAudioWorkletNode(name, options) {\n return createAudioWorkletNode(this.rawContext, name, options);\n }\n /**\n * Add an AudioWorkletProcessor module\n * @param url The url of the module\n * @param name The name of the module\n */\n addAudioWorkletModule(url, name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n Debug_assert(TypeCheck_isDefined(this.rawContext.audioWorklet), "AudioWorkletNode is only available in a secure context (https or localhost)");\n if (!this._workletModules.has(name)) {\n this._workletModules.set(name, this.rawContext.audioWorklet.addModule(url));\n }\n yield this._workletModules.get(name);\n });\n }\n /**\n * Returns a promise which resolves when all of the worklets have been loaded on this context\n */\n workletsAreReady() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const promises = [];\n this._workletModules.forEach((promise) => promises.push(promise));\n yield Promise.all(promises);\n });\n }\n //---------------------------\n // TICKER\n //---------------------------\n /**\n * How often the interval callback is invoked.\n * This number corresponds to how responsive the scheduling\n * can be. context.updateInterval + context.lookAhead gives you the\n * total latency between scheduling an event and hearing it.\n */\n get updateInterval() {\n return this._ticker.updateInterval;\n }\n set updateInterval(interval) {\n this._ticker.updateInterval = interval;\n }\n /**\n * What the source of the clock is, either "worker" (default),\n * "timeout", or "offline" (none).\n */\n get clockSource() {\n return this._ticker.type;\n }\n set clockSource(type) {\n this._ticker.type = type;\n }\n /**\n * The type of playback, which affects tradeoffs between audio\n * output latency and responsiveness.\n * In addition to setting the value in seconds, the latencyHint also\n * accepts the strings "interactive" (prioritizes low latency),\n * "playback" (prioritizes sustained playback), "balanced" (balances\n * latency and performance).\n * @example\n * // prioritize sustained playback\n * const context = new Tone.Context({ latencyHint: "playback" });\n * // set this context as the global Context\n * Tone.setContext(context);\n * // the global context is gettable with Tone.getContext()\n * console.log(Tone.getContext().latencyHint);\n */\n get latencyHint() {\n return this._latencyHint;\n }\n /**\n * Update the lookAhead and updateInterval based on the latencyHint\n */\n _setLatencyHint(hint) {\n let lookAheadValue = 0;\n this._latencyHint = hint;\n if (TypeCheck_isString(hint)) {\n switch (hint) {\n case "interactive":\n lookAheadValue = 0.1;\n break;\n case "playback":\n lookAheadValue = 0.5;\n break;\n case "balanced":\n lookAheadValue = 0.25;\n break;\n }\n }\n this.lookAhead = lookAheadValue;\n this.updateInterval = lookAheadValue / 2;\n }\n /**\n * The unwrapped AudioContext or OfflineAudioContext\n */\n get rawContext() {\n return this._context;\n }\n /**\n * The current audio context time plus a short [[lookAhead]].\n */\n now() {\n return this._context.currentTime + this.lookAhead;\n }\n /**\n * The current audio context time without the [[lookAhead]].\n * In most cases it is better to use [[now]] instead of [[immediate]] since\n * with [[now]] the [[lookAhead]] is applied equally to _all_ components including internal components,\n * to making sure that everything is scheduled in sync. Mixing [[now]] and [[immediate]]\n * can cause some timing issues. If no lookAhead is desired, you can set the [[lookAhead]] to `0`.\n */\n immediate() {\n return this._context.currentTime;\n }\n /**\n * Starts the audio context from a suspended state. This is required\n * to initially start the AudioContext. See [[Tone.start]]\n */\n resume() {\n if (isAudioContext(this._context)) {\n return this._context.resume();\n }\n else {\n return Promise.resolve();\n }\n }\n /**\n * Close the context. Once closed, the context can no longer be used and\n * any AudioNodes created from the context will be silent.\n */\n close() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n if (isAudioContext(this._context)) {\n yield this._context.close();\n }\n if (this._initialized) {\n closeContext(this);\n }\n });\n }\n /**\n * **Internal** Generate a looped buffer at some constant value.\n */\n getConstant(val) {\n if (this._constants.has(val)) {\n return this._constants.get(val);\n }\n else {\n const buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n const arr = buffer.getChannelData(0);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = val;\n }\n const constant = this._context.createBufferSource();\n constant.channelCount = 1;\n constant.channelCountMode = "explicit";\n constant.buffer = buffer;\n constant.loop = true;\n constant.start(0);\n this._constants.set(val, constant);\n return constant;\n }\n }\n /**\n * Clean up. Also closes the audio context.\n */\n dispose() {\n super.dispose();\n this._ticker.dispose();\n this._timeouts.dispose();\n Object.keys(this._constants).map((val) => this._constants[val].disconnect());\n return this;\n }\n //---------------------------\n // TIMEOUTS\n //---------------------------\n /**\n * The private loop which keeps track of the context scheduled timeouts\n * Is invoked from the clock source\n */\n _timeoutLoop() {\n const now = this.now();\n let firstEvent = this._timeouts.peek();\n while (this._timeouts.length && firstEvent && firstEvent.time <= now) {\n // invoke the callback\n firstEvent.callback();\n // shift the first event off\n this._timeouts.shift();\n // get the next one\n firstEvent = this._timeouts.peek();\n }\n }\n /**\n * A setTimeout which is guaranteed by the clock source.\n * Also runs in the offline context.\n * @param fn The callback to invoke\n * @param timeout The timeout in seconds\n * @returns ID to use when invoking Context.clearTimeout\n */\n setTimeout(fn, timeout) {\n this._timeoutIds++;\n const now = this.now();\n this._timeouts.add({\n callback: fn,\n id: this._timeoutIds,\n time: now + timeout,\n });\n return this._timeoutIds;\n }\n /**\n * Clears a previously scheduled timeout with Tone.context.setTimeout\n * @param id The ID returned from setTimeout\n */\n clearTimeout(id) {\n this._timeouts.forEach((event) => {\n if (event.id === id) {\n this._timeouts.remove(event);\n }\n });\n return this;\n }\n /**\n * Clear the function scheduled by [[setInterval]]\n */\n clearInterval(id) {\n return this.clearTimeout(id);\n }\n /**\n * Adds a repeating event to the context\'s callback clock\n */\n setInterval(fn, interval) {\n const id = ++this._timeoutIds;\n const intervalFn = () => {\n const now = this.now();\n this._timeouts.add({\n callback: () => {\n // invoke the callback\n fn();\n // invoke the event to repeat it\n intervalFn();\n },\n id,\n time: now + interval,\n });\n };\n // kick it off\n intervalFn();\n return id;\n }\n}\n//# sourceMappingURL=Context.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/DummyContext.js\n\n\nclass DummyContext extends BaseContext {\n constructor() {\n super(...arguments);\n this.lookAhead = 0;\n this.latencyHint = 0;\n this.isOffline = false;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return {};\n }\n createOscillator() {\n return {};\n }\n createBufferSource() {\n return {};\n }\n createBiquadFilter() {\n return {};\n }\n createBuffer(_numberOfChannels, _length, _sampleRate) {\n return {};\n }\n createChannelMerger(_numberOfInputs) {\n return {};\n }\n createChannelSplitter(_numberOfOutputs) {\n return {};\n }\n createConstantSource() {\n return {};\n }\n createConvolver() {\n return {};\n }\n createDelay(_maxDelayTime) {\n return {};\n }\n createDynamicsCompressor() {\n return {};\n }\n createGain() {\n return {};\n }\n createIIRFilter(_feedForward, _feedback) {\n return {};\n }\n createPanner() {\n return {};\n }\n createPeriodicWave(_real, _imag, _constraints) {\n return {};\n }\n createStereoPanner() {\n return {};\n }\n createWaveShaper() {\n return {};\n }\n createMediaStreamSource(_stream) {\n return {};\n }\n createMediaElementSource(_element) {\n return {};\n }\n createMediaStreamDestination() {\n return {};\n }\n decodeAudioData(_audioData) {\n return Promise.resolve({});\n }\n //---------------------------\n // TONE AUDIO CONTEXT METHODS\n //---------------------------\n createAudioWorkletNode(_name, _options) {\n return {};\n }\n get rawContext() {\n return {};\n }\n addAudioWorkletModule(_url, _name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return Promise.resolve();\n });\n }\n resume() {\n return Promise.resolve();\n }\n setTimeout(_fn, _timeout) {\n return 0;\n }\n clearTimeout(_id) {\n return this;\n }\n setInterval(_fn, _interval) {\n return 0;\n }\n clearInterval(_id) {\n return this;\n }\n getConstant(_val) {\n return {};\n }\n get currentTime() {\n return 0;\n }\n get state() {\n return {};\n }\n get sampleRate() {\n return 0;\n }\n get listener() {\n return {};\n }\n get transport() {\n return {};\n }\n get draw() {\n return {};\n }\n set draw(_d) { }\n get destination() {\n return {};\n }\n set destination(_d) { }\n now() {\n return 0;\n }\n immediate() {\n return 0;\n }\n}\n//# sourceMappingURL=DummyContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Interface.js\n\n/**\n * Make the property not writable using `defineProperty`. Internal use only.\n */\nfunction Interface_readOnly(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_readOnly(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n enumerable: true,\n writable: false,\n });\n }\n}\n/**\n * Make an attribute writeable. Internal use only.\n */\nfunction Interface_writable(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_writable(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n writable: true,\n });\n }\n}\nconst Interface_noOp = () => {\n // no operation here!\n};\n//# sourceMappingURL=Interface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffer.js\n\n\n\n\n\n\n\n\n/**\n * AudioBuffer loading and storage. ToneAudioBuffer is used internally by all\n * classes that make requests for audio files such as Tone.Player,\n * Tone.Sampler and Tone.Convolver.\n * @example\n * const buffer = new Tone.ToneAudioBuffer("https://tonejs.github.io/audio/casio/A1.mp3", () => {\n * \tconsole.log("loaded");\n * });\n * @category Core\n */\nclass ToneAudioBuffer_ToneAudioBuffer extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffer";\n /**\n * Callback when the buffer is loaded.\n */\n this.onload = Interface_noOp;\n const options = Defaults_optionsFromArguments(ToneAudioBuffer_ToneAudioBuffer.getDefaults(), arguments, ["url", "onload", "onerror"]);\n this.reverse = options.reverse;\n this.onload = options.onload;\n if (options.url && isAudioBuffer(options.url) || options.url instanceof ToneAudioBuffer_ToneAudioBuffer) {\n this.set(options.url);\n }\n else if (TypeCheck_isString(options.url)) {\n // initiate the download\n this.load(options.url).catch(options.onerror);\n }\n }\n static getDefaults() {\n return {\n onerror: Interface_noOp,\n onload: Interface_noOp,\n reverse: false,\n };\n }\n /**\n * The sample rate of the AudioBuffer\n */\n get sampleRate() {\n if (this._buffer) {\n return this._buffer.sampleRate;\n }\n else {\n return Global_getContext().sampleRate;\n }\n }\n /**\n * Pass in an AudioBuffer or ToneAudioBuffer to set the value of this buffer.\n */\n set(buffer) {\n if (buffer instanceof ToneAudioBuffer_ToneAudioBuffer) {\n // if it\'s loaded, set it\n if (buffer.loaded) {\n this._buffer = buffer.get();\n }\n else {\n // otherwise when it\'s loaded, invoke it\'s callback\n buffer.onload = () => {\n this.set(buffer);\n this.onload(this);\n };\n }\n }\n else {\n this._buffer = buffer;\n }\n // reverse it initially\n if (this._reversed) {\n this._reverse();\n }\n return this;\n }\n /**\n * The audio buffer stored in the object.\n */\n get() {\n return this._buffer;\n }\n /**\n * Makes an fetch request for the selected url then decodes the file as an audio buffer.\n * Invokes the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n * @returns A Promise which resolves with this ToneAudioBuffer\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const doneLoading = ToneAudioBuffer_ToneAudioBuffer.load(url).then(audioBuffer => {\n this.set(audioBuffer);\n // invoke the onload method\n this.onload(this);\n });\n ToneAudioBuffer_ToneAudioBuffer.downloads.push(doneLoading);\n try {\n yield doneLoading;\n }\n finally {\n // remove the downloaded file\n const index = ToneAudioBuffer_ToneAudioBuffer.downloads.indexOf(doneLoading);\n ToneAudioBuffer_ToneAudioBuffer.downloads.splice(index, 1);\n }\n return this;\n });\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._buffer = undefined;\n return this;\n }\n /**\n * Set the audio buffer from the array.\n * To create a multichannel AudioBuffer, pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n */\n fromArray(array) {\n const isMultidimensional = TypeCheck_isArray(array) && array[0].length > 0;\n const channels = isMultidimensional ? array.length : 1;\n const len = isMultidimensional ? array[0].length : array.length;\n const context = Global_getContext();\n const buffer = context.createBuffer(channels, len, context.sampleRate);\n const multiChannelArray = !isMultidimensional && channels === 1 ?\n [array] : array;\n for (let c = 0; c < channels; c++) {\n buffer.copyToChannel(multiChannelArray[c], c);\n }\n this._buffer = buffer;\n return this;\n }\n /**\n * Sums multiple channels into 1 channel\n * @param chanNum Optionally only copy a single channel from the array.\n */\n toMono(chanNum) {\n if (TypeCheck_isNumber(chanNum)) {\n this.fromArray(this.toArray(chanNum));\n }\n else {\n let outputArray = new Float32Array(this.length);\n const numChannels = this.numberOfChannels;\n for (let channel = 0; channel < numChannels; channel++) {\n const channelArray = this.toArray(channel);\n for (let i = 0; i < channelArray.length; i++) {\n outputArray[i] += channelArray[i];\n }\n }\n // divide by the number of channels\n outputArray = outputArray.map(sample => sample / numChannels);\n this.fromArray(outputArray);\n }\n return this;\n }\n /**\n * Get the buffer as an array. Single channel buffers will return a 1-dimensional\n * Float32Array, and multichannel buffers will return multidimensional arrays.\n * @param channel Optionally only copy a single channel from the array.\n */\n toArray(channel) {\n if (TypeCheck_isNumber(channel)) {\n return this.getChannelData(channel);\n }\n else if (this.numberOfChannels === 1) {\n return this.toArray(0);\n }\n else {\n const ret = [];\n for (let c = 0; c < this.numberOfChannels; c++) {\n ret[c] = this.getChannelData(c);\n }\n return ret;\n }\n }\n /**\n * Returns the Float32Array representing the PCM audio data for the specific channel.\n * @param channel The channel number to return\n * @return The audio as a TypedArray\n */\n getChannelData(channel) {\n if (this._buffer) {\n return this._buffer.getChannelData(channel);\n }\n else {\n return new Float32Array(0);\n }\n }\n /**\n * Cut a subsection of the array and return a buffer of the\n * subsection. Does not modify the original buffer\n * @param start The time to start the slice\n * @param end The end time to slice. If none is given will default to the end of the buffer\n */\n slice(start, end = this.duration) {\n const startSamples = Math.floor(start * this.sampleRate);\n const endSamples = Math.floor(end * this.sampleRate);\n Debug_assert(startSamples < endSamples, "The start time must be less than the end time");\n const length = endSamples - startSamples;\n const retBuffer = Global_getContext().createBuffer(this.numberOfChannels, length, this.sampleRate);\n for (let channel = 0; channel < this.numberOfChannels; channel++) {\n retBuffer.copyToChannel(this.getChannelData(channel).subarray(startSamples, endSamples), channel);\n }\n return new ToneAudioBuffer_ToneAudioBuffer(retBuffer);\n }\n /**\n * Reverse the buffer.\n */\n _reverse() {\n if (this.loaded) {\n for (let i = 0; i < this.numberOfChannels; i++) {\n this.getChannelData(i).reverse();\n }\n }\n return this;\n }\n /**\n * If the buffer is loaded or not\n */\n get loaded() {\n return this.length > 0;\n }\n /**\n * The duration of the buffer in seconds.\n */\n get duration() {\n if (this._buffer) {\n return this._buffer.duration;\n }\n else {\n return 0;\n }\n }\n /**\n * The length of the buffer in samples\n */\n get length() {\n if (this._buffer) {\n return this._buffer.length;\n }\n else {\n return 0;\n }\n }\n /**\n * The number of discrete audio channels. Returns 0 if no buffer is loaded.\n */\n get numberOfChannels() {\n if (this._buffer) {\n return this._buffer.numberOfChannels;\n }\n else {\n return 0;\n }\n }\n /**\n * Reverse the buffer.\n */\n get reverse() {\n return this._reversed;\n }\n set reverse(rev) {\n if (this._reversed !== rev) {\n this._reversed = rev;\n this._reverse();\n }\n }\n /**\n * Create a ToneAudioBuffer from the array. To create a multichannel AudioBuffer,\n * pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n * @return A ToneAudioBuffer created from the array\n */\n static fromArray(array) {\n return (new ToneAudioBuffer_ToneAudioBuffer()).fromArray(array);\n }\n /**\n * Creates a ToneAudioBuffer from a URL, returns a promise which resolves to a ToneAudioBuffer\n * @param url The url to load.\n * @return A promise which resolves to a ToneAudioBuffer\n */\n static fromUrl(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const buffer = new ToneAudioBuffer_ToneAudioBuffer();\n return yield buffer.load(url);\n });\n }\n /**\n * Loads a url using fetch and returns the AudioBuffer.\n */\n static load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // test if the url contains multiple extensions\n const matches = url.match(/\\[([^\\]\\[]+\\|.+)\\]$/);\n if (matches) {\n const extensions = matches[1].split("|");\n let extension = extensions[0];\n for (const ext of extensions) {\n if (ToneAudioBuffer_ToneAudioBuffer.supportsType(ext)) {\n extension = ext;\n break;\n }\n }\n url = url.replace(matches[0], extension);\n }\n // make sure there is a slash between the baseUrl and the url\n const baseUrl = ToneAudioBuffer_ToneAudioBuffer.baseUrl === "" || ToneAudioBuffer_ToneAudioBuffer.baseUrl.endsWith("/") ? ToneAudioBuffer_ToneAudioBuffer.baseUrl : ToneAudioBuffer_ToneAudioBuffer.baseUrl + "/";\n const response = yield fetch(baseUrl + url);\n if (!response.ok) {\n throw new Error(`could not load url: ${url}`);\n }\n const arrayBuffer = yield response.arrayBuffer();\n const audioBuffer = yield Global_getContext().decodeAudioData(arrayBuffer);\n return audioBuffer;\n });\n }\n /**\n * Checks a url\'s extension to see if the current browser can play that file type.\n * @param url The url/extension to test\n * @return If the file extension can be played\n * @static\n * @example\n * Tone.ToneAudioBuffer.supportsType("wav"); // returns true\n * Tone.ToneAudioBuffer.supportsType("path/to/file.wav"); // returns true\n */\n static supportsType(url) {\n const extensions = url.split(".");\n const extension = extensions[extensions.length - 1];\n const response = document.createElement("audio").canPlayType("audio/" + extension);\n return response !== "";\n }\n /**\n * Returns a Promise which resolves when all of the buffers have loaded\n */\n static loaded() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // this makes sure that the function is always async\n yield Promise.resolve();\n while (ToneAudioBuffer_ToneAudioBuffer.downloads.length) {\n yield ToneAudioBuffer_ToneAudioBuffer.downloads[0];\n }\n });\n }\n}\n//-------------------------------------\n// STATIC METHODS\n//-------------------------------------\n/**\n * A path which is prefixed before every url.\n */\nToneAudioBuffer_ToneAudioBuffer.baseUrl = "";\n/**\n * All of the downloads\n */\nToneAudioBuffer_ToneAudioBuffer.downloads = [];\n//# sourceMappingURL=ToneAudioBuffer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/OfflineContext.js\n\n\n\n\n\n/**\n * Wrapper around the OfflineAudioContext\n * @category Core\n * @example\n * // generate a single channel, 0.5 second buffer\n * const context = new Tone.OfflineContext(1, 0.5, 44100);\n * const osc = new Tone.Oscillator({ context });\n * context.render().then(buffer => {\n * \tconsole.log(buffer.numberOfChannels, buffer.duration);\n * });\n */\nclass OfflineContext_OfflineContext extends Context {\n constructor() {\n super({\n clockSource: "offline",\n context: isOfflineAudioContext(arguments[0]) ?\n arguments[0] : createOfflineAudioContext(arguments[0], arguments[1] * arguments[2], arguments[2]),\n lookAhead: 0,\n updateInterval: isOfflineAudioContext(arguments[0]) ?\n 128 / arguments[0].sampleRate : 128 / arguments[2],\n });\n this.name = "OfflineContext";\n /**\n * An artificial clock source\n */\n this._currentTime = 0;\n this.isOffline = true;\n this._duration = isOfflineAudioContext(arguments[0]) ?\n arguments[0].length / arguments[0].sampleRate : arguments[1];\n }\n /**\n * Override the now method to point to the internal clock time\n */\n now() {\n return this._currentTime;\n }\n /**\n * Same as this.now()\n */\n get currentTime() {\n return this._currentTime;\n }\n /**\n * Render just the clock portion of the audio context.\n */\n _renderClock(asynchronous) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n let index = 0;\n while (this._duration - this._currentTime >= 0) {\n // invoke all the callbacks on that time\n this.emit("tick");\n // increment the clock in block-sized chunks\n this._currentTime += 128 / this.sampleRate;\n // yield once a second of audio\n index++;\n const yieldEvery = Math.floor(this.sampleRate / 128);\n if (asynchronous && index % yieldEvery === 0) {\n yield new Promise(done => setTimeout(done, 1));\n }\n }\n });\n }\n /**\n * Render the output of the OfflineContext\n * @param asynchronous If the clock should be rendered asynchronously, which will not block the main thread, but be slightly slower.\n */\n render(asynchronous = true) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this.workletsAreReady();\n yield this._renderClock(asynchronous);\n const buffer = yield this._context.startRendering();\n return new ToneAudioBuffer_ToneAudioBuffer(buffer);\n });\n }\n /**\n * Close the context\n */\n close() {\n return Promise.resolve();\n }\n}\n//# sourceMappingURL=OfflineContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Global.js\n\n\n\n\n\n\n/**\n * This dummy context is used to avoid throwing immediate errors when importing in Node.js\n */\nconst dummyContext = new DummyContext();\n/**\n * The global audio context which is getable and assignable through\n * getContext and setContext\n */\nlet globalContext = dummyContext;\n/**\n * Returns the default system-wide [[Context]]\n * @category Core\n */\nfunction Global_getContext() {\n if (globalContext === dummyContext && hasAudioContext) {\n Global_setContext(new Context());\n }\n return globalContext;\n}\n/**\n * Set the default audio context\n * @category Core\n */\nfunction Global_setContext(context) {\n if (isAudioContext(context)) {\n globalContext = new Context(context);\n }\n else if (isOfflineAudioContext(context)) {\n globalContext = new OfflineContext_OfflineContext(context);\n }\n else {\n globalContext = context;\n }\n}\n/**\n * Most browsers will not play _any_ audio until a user\n * clicks something (like a play button). Invoke this method\n * on a click or keypress event handler to start the audio context.\n * More about the Autoplay policy\n * [here](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio)\n * @example\n * document.querySelector("button").addEventListener("click", async () => {\n * \tawait Tone.start();\n * \tconsole.log("context started");\n * });\n * @category Core\n */\nfunction start() {\n return globalContext.resume();\n}\n/**\n * Log Tone.js + version in the console.\n */\nif (AudioContext_theWindow && !AudioContext_theWindow.TONE_SILENCE_LOGGING) {\n let prefix = "v";\n if (version === "dev") {\n prefix = "";\n }\n const printString = ` * Tone.js ${prefix}${version} * `;\n // eslint-disable-next-line no-console\n console.log(`%c${printString}`, "background: #000; color: #fff");\n}\n//# sourceMappingURL=Global.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Conversions.js\n/**\n * Equal power gain scale. Good for cross-fading.\n * @param percent (0-1)\n */\nfunction equalPowerScale(percent) {\n const piFactor = 0.5 * Math.PI;\n return Math.sin(percent * piFactor);\n}\n/**\n * Convert decibels into gain.\n */\nfunction Conversions_dbToGain(db) {\n return Math.pow(10, db / 20);\n}\n/**\n * Convert gain to decibels.\n */\nfunction Conversions_gainToDb(gain) {\n return 20 * (Math.log(gain) / Math.LN10);\n}\n/**\n * Convert an interval (in semitones) to a frequency ratio.\n * @param interval the number of semitones above the base note\n * @example\n * Tone.intervalToFrequencyRatio(0); // 1\n * Tone.intervalToFrequencyRatio(12); // 2\n * Tone.intervalToFrequencyRatio(-12); // 0.5\n */\nfunction Conversions_intervalToFrequencyRatio(interval) {\n return Math.pow(2, (interval / 12));\n}\n/**\n * The Global [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\nlet A4 = 440;\nfunction getA4() {\n return A4;\n}\nfunction setA4(freq) {\n A4 = freq;\n}\n/**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n * @example\n * Tone.ftom(440); // returns 69\n */\nfunction Conversions_ftom(frequency) {\n return Math.round(ftomf(frequency));\n}\n/**\n * Convert a frequency to a floating point midi value\n */\nfunction ftomf(frequency) {\n return 69 + 12 * Math.log2(frequency / A4);\n}\n/**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n * @example\n * Tone.mtof(69); // 440\n */\nfunction Conversions_mtof(midi) {\n return A4 * Math.pow(2, (midi - 69) / 12);\n}\n//# sourceMappingURL=Conversions.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TimeBase.js\n\n\n/**\n * TimeBase is a flexible encoding of time which can be evaluated to and from a string.\n */\nclass TimeBaseClass extends Tone {\n /**\n * @param context The context associated with the time value. Used to compute\n * Transport and context-relative timing.\n * @param value The time value as a number, string or object\n * @param units Unit values\n */\n constructor(context, value, units) {\n super();\n /**\n * The default units\n */\n this.defaultUnits = "s";\n this._val = value;\n this._units = units;\n this.context = context;\n this._expressions = this._getExpressions();\n }\n /**\n * All of the time encoding expressions\n */\n _getExpressions() {\n return {\n hz: {\n method: (value) => {\n return this._frequencyToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)hz$/i,\n },\n i: {\n method: (value) => {\n return this._ticksToUnits(parseInt(value, 10));\n },\n regexp: /^(\\d+)i$/i,\n },\n m: {\n method: (value) => {\n return this._beatsToUnits(parseInt(value, 10) * this._getTimeSignature());\n },\n regexp: /^(\\d+)m$/i,\n },\n n: {\n method: (value, dot) => {\n const numericValue = parseInt(value, 10);\n const scalar = dot === "." ? 1.5 : 1;\n if (numericValue === 1) {\n return this._beatsToUnits(this._getTimeSignature()) * scalar;\n }\n else {\n return this._beatsToUnits(4 / numericValue) * scalar;\n }\n },\n regexp: /^(\\d+)n(\\.?)$/i,\n },\n number: {\n method: (value) => {\n return this._expressions[this.defaultUnits].method.call(this, value);\n },\n regexp: /^(\\d+(?:\\.\\d+)?)$/,\n },\n s: {\n method: (value) => {\n return this._secondsToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)s$/,\n },\n samples: {\n method: (value) => {\n return parseInt(value, 10) / this.context.sampleRate;\n },\n regexp: /^(\\d+)samples$/,\n },\n t: {\n method: (value) => {\n const numericValue = parseInt(value, 10);\n return this._beatsToUnits(8 / (Math.floor(numericValue) * 3));\n },\n regexp: /^(\\d+)t$/i,\n },\n tr: {\n method: (m, q, s) => {\n let total = 0;\n if (m && m !== "0") {\n total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total += this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total += this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?$/,\n },\n };\n }\n //-------------------------------------\n // \tVALUE OF\n //-------------------------------------\n /**\n * Evaluate the time value. Returns the time in seconds.\n */\n valueOf() {\n if (this._val instanceof TimeBaseClass) {\n this.fromType(this._val);\n }\n if (TypeCheck_isUndef(this._val)) {\n return this._noArg();\n }\n else if (TypeCheck_isString(this._val) && TypeCheck_isUndef(this._units)) {\n for (const units in this._expressions) {\n if (this._expressions[units].regexp.test(this._val.trim())) {\n this._units = units;\n break;\n }\n }\n }\n else if (TypeCheck_isObject(this._val)) {\n let total = 0;\n for (const typeName in this._val) {\n if (TypeCheck_isDefined(this._val[typeName])) {\n const quantity = this._val[typeName];\n // @ts-ignore\n const time = (new this.constructor(this.context, typeName)).valueOf() * quantity;\n total += time;\n }\n }\n return total;\n }\n if (TypeCheck_isDefined(this._units)) {\n const expr = this._expressions[this._units];\n const matching = this._val.toString().trim().match(expr.regexp);\n if (matching) {\n return expr.method.apply(this, matching.slice(1));\n }\n else {\n return expr.method.call(this, this._val);\n }\n }\n else if (TypeCheck_isString(this._val)) {\n return parseFloat(this._val);\n }\n else {\n return this._val;\n }\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return 1 / freq;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return (60 / this._getBpm()) * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return seconds;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return (ticks * (this._beatsToUnits(1)) / this._getPPQ());\n }\n /**\n * With no arguments, return \'now\'\n */\n _noArg() {\n return this._now();\n }\n //-------------------------------------\n // \tTEMPO CONVERSIONS\n //-------------------------------------\n /**\n * Return the bpm\n */\n _getBpm() {\n return this.context.transport.bpm.value;\n }\n /**\n * Return the timeSignature\n */\n _getTimeSignature() {\n return this.context.transport.timeSignature;\n }\n /**\n * Return the PPQ or 192 if Transport is not available\n */\n _getPPQ() {\n return this.context.transport.PPQ;\n }\n //-------------------------------------\n // \tCONVERSION INTERFACE\n //-------------------------------------\n /**\n * Coerce a time type into this units type.\n * @param type Any time type units\n */\n fromType(type) {\n this._units = undefined;\n switch (this.defaultUnits) {\n case "s":\n this._val = type.toSeconds();\n break;\n case "i":\n this._val = type.toTicks();\n break;\n case "hz":\n this._val = type.toFrequency();\n break;\n case "midi":\n this._val = type.toMidi();\n break;\n }\n return this;\n }\n /**\n * Return the value in hertz\n */\n toFrequency() {\n return 1 / this.toSeconds();\n }\n /**\n * Return the time in samples\n */\n toSamples() {\n return this.toSeconds() * this.context.sampleRate;\n }\n /**\n * Return the time in milliseconds.\n */\n toMilliseconds() {\n return this.toSeconds() * 1000;\n }\n}\n//# sourceMappingURL=TimeBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Time.js\n\n\n\n/**\n * TimeClass is a primitive type for encoding and decoding Time values.\n * TimeClass can be passed into the parameter of any method which takes time as an argument.\n * @param val The time value.\n * @param units The units of the value.\n * @example\n * const time = Tone.Time("4n"); // a quarter note\n * @category Unit\n */\nclass TimeClass extends TimeBaseClass {\n constructor() {\n super(...arguments);\n this.name = "TimeClass";\n }\n _getExpressions() {\n return Object.assign(super._getExpressions(), {\n now: {\n method: (capture) => {\n return this._now() + new this.constructor(this.context, capture).valueOf();\n },\n regexp: /^\\+(.+)/,\n },\n quantize: {\n method: (capture) => {\n const quantTo = new TimeClass(this.context, capture).valueOf();\n return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo));\n },\n regexp: /^@(.+)/,\n },\n });\n }\n /**\n * Quantize the time by the given subdivision. Optionally add a\n * percentage which will move the time value towards the ideal\n * quantized value by that percentage.\n * @param subdiv The subdivision to quantize to\n * @param percent Move the time value towards the quantized value by a percentage.\n * @example\n * Tone.Time(21).quantize(2); // returns 22\n * Tone.Time(0.6).quantize("4n", 0.5); // returns 0.55\n */\n quantize(subdiv, percent = 1) {\n const subdivision = new this.constructor(this.context, subdiv).valueOf();\n const value = this.valueOf();\n const multiple = Math.round(value / subdivision);\n const ideal = multiple * subdivision;\n const diff = ideal - value;\n return value + diff * percent;\n }\n //-------------------------------------\n // CONVERSIONS\n //-------------------------------------\n /**\n * Convert a Time to Notation. The notation values are will be the\n * closest representation between 1m to 128th note.\n * @return {Notation}\n * @example\n * // if the Transport is at 120bpm:\n * Tone.Time(2).toNotation(); // returns "1m"\n */\n toNotation() {\n const time = this.toSeconds();\n const testNotations = ["1m"];\n for (let power = 1; power < 9; power++) {\n const subdiv = Math.pow(2, power);\n testNotations.push(subdiv + "n.");\n testNotations.push(subdiv + "n");\n testNotations.push(subdiv + "t");\n }\n testNotations.push("0");\n // find the closets notation representation\n let closest = testNotations[0];\n let closestSeconds = new TimeClass(this.context, testNotations[0]).toSeconds();\n testNotations.forEach(notation => {\n const notationSeconds = new TimeClass(this.context, notation).toSeconds();\n if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) {\n closest = notation;\n closestSeconds = notationSeconds;\n }\n });\n return closest;\n }\n /**\n * Return the time encoded as Bars:Beats:Sixteenths.\n */\n toBarsBeatsSixteenths() {\n const quarterTime = this._beatsToUnits(1);\n let quarters = this.valueOf() / quarterTime;\n quarters = parseFloat(quarters.toFixed(4));\n const measures = Math.floor(quarters / this._getTimeSignature());\n let sixteenths = (quarters % 1) * 4;\n quarters = Math.floor(quarters) % this._getTimeSignature();\n const sixteenthString = sixteenths.toString();\n if (sixteenthString.length > 3) {\n // the additional parseFloat removes insignificant trailing zeroes\n sixteenths = parseFloat(parseFloat(sixteenthString).toFixed(3));\n }\n const progress = [measures, quarters, sixteenths];\n return progress.join(":");\n }\n /**\n * Return the time in ticks.\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.round(quarters * this._getPPQ());\n }\n /**\n * Return the time in seconds.\n */\n toSeconds() {\n return this.valueOf();\n }\n /**\n * Return the value as a midi note.\n */\n toMidi() {\n return Conversions_ftom(this.toFrequency());\n }\n _now() {\n return this.context.now();\n }\n}\n/**\n * Create a TimeClass from a time string or number. The time is computed against the\n * global Tone.Context. To use a specific context, use [[TimeClass]]\n * @param value A value which represents time\n * @param units The value\'s units if they can\'t be inferred by the value.\n * @category Unit\n * @example\n * const time = Tone.Time("4n").toSeconds();\n * console.log(time);\n * @example\n * const note = Tone.Time(1).toNotation();\n * console.log(note);\n * @example\n * const freq = Tone.Time(0.5).toFrequency();\n * console.log(freq);\n */\nfunction Time(value, units) {\n return new TimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=Time.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Frequency.js\n\n\n\n\n/**\n * Frequency is a primitive type for encoding Frequency values.\n * Eventually all time values are evaluated to hertz using the `valueOf` method.\n * @example\n * Tone.Frequency("C3"); // 261\n * Tone.Frequency(38, "midi");\n * Tone.Frequency("C3").transpose(4);\n * @category Unit\n */\nclass Frequency_FrequencyClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "Frequency";\n this.defaultUnits = "hz";\n }\n /**\n * The [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\n static get A4() {\n return getA4();\n }\n static set A4(freq) {\n setA4(freq);\n }\n //-------------------------------------\n // \tAUGMENT BASE EXPRESSIONS\n //-------------------------------------\n _getExpressions() {\n return Object.assign({}, super._getExpressions(), {\n midi: {\n regexp: /^(\\d+(?:\\.\\d+)?midi)/,\n method(value) {\n if (this.defaultUnits === "midi") {\n return value;\n }\n else {\n return Frequency_FrequencyClass.mtof(value);\n }\n },\n },\n note: {\n regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n method(pitch, octave) {\n const index = noteToScaleIndex[pitch.toLowerCase()];\n const noteNumber = index + (parseInt(octave, 10) + 1) * 12;\n if (this.defaultUnits === "midi") {\n return noteNumber;\n }\n else {\n return Frequency_FrequencyClass.mtof(noteNumber);\n }\n },\n },\n tr: {\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n method(m, q, s) {\n let total = 1;\n if (m && m !== "0") {\n total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total *= this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total *= this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n },\n });\n }\n //-------------------------------------\n // \tEXPRESSIONS\n //-------------------------------------\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed frequency\n * @example\n * Tone.Frequency("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Frequency_FrequencyClass(this.context, this.valueOf() * Conversions_intervalToFrequencyRatio(interval));\n }\n /**\n * Takes an array of semitone intervals and returns\n * an array of frequencies transposed by those intervals.\n * @return Returns an array of Frequencies\n * @example\n * Tone.Frequency("A4").harmonize([0, 3, 7]); // ["A4", "C5", "E5"]\n */\n harmonize(intervals) {\n return intervals.map(interval => {\n return this.transpose(interval);\n });\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Frequency("C4").toMidi(); // 60\n */\n toMidi() {\n return Conversions_ftom(this.valueOf());\n }\n /**\n * Return the value of the frequency in Scientific Pitch Notation\n * @example\n * Tone.Frequency(69, "midi").toNote(); // "A4"\n */\n toNote() {\n const freq = this.toFrequency();\n const log = Math.log2(freq / Frequency_FrequencyClass.A4);\n let noteNumber = Math.round(12 * log) + 57;\n const octave = Math.floor(noteNumber / 12);\n if (octave < 0) {\n noteNumber += -12 * octave;\n }\n const noteName = scaleIndexToNote[noteNumber % 12];\n return noteName + octave.toString();\n }\n /**\n * Return the duration of one cycle in seconds.\n */\n toSeconds() {\n return 1 / super.toSeconds();\n }\n /**\n * Return the duration of one cycle in ticks\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.floor(quarters * this._getPPQ());\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS HELPERS\n //-------------------------------------\n /**\n * With no arguments, return 0\n */\n _noArg() {\n return 0;\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return freq;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return 1 / ((ticks * 60) / (this._getBpm() * this._getPPQ()));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return 1 / super._beatsToUnits(beats);\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return 1 / seconds;\n }\n /**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n */\n static mtof(midi) {\n return Conversions_mtof(midi);\n }\n /**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n */\n static ftom(frequency) {\n return Conversions_ftom(frequency);\n }\n}\n//-------------------------------------\n// \tFREQUENCY CONVERSIONS\n//-------------------------------------\n/**\n * Note to scale index.\n * @hidden\n */\nconst noteToScaleIndex = {\n cbb: -2, cb: -1, c: 0, "c#": 1, cx: 2,\n dbb: 0, db: 1, d: 2, "d#": 3, dx: 4,\n ebb: 2, eb: 3, e: 4, "e#": 5, ex: 6,\n fbb: 3, fb: 4, f: 5, "f#": 6, fx: 7,\n gbb: 5, gb: 6, g: 7, "g#": 8, gx: 9,\n abb: 7, ab: 8, a: 9, "a#": 10, ax: 11,\n bbb: 9, bb: 10, b: 11, "b#": 12, bx: 13,\n};\n/**\n * scale index to note (sharps)\n * @hidden\n */\nconst scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n * @example\n * const midi = Tone.Frequency("C3").toMidi();\n * console.log(midi);\n * @example\n * const hertz = Tone.Frequency(38, "midi").toFrequency();\n * console.log(hertz);\n */\nfunction Frequency(value, units) {\n return new Frequency_FrequencyClass(getContext(), value, units);\n}\n//# sourceMappingURL=Frequency.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TransportTime.js\n\n\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to Tone.Time, but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nclass TransportTime_TransportTimeClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "TransportTime";\n }\n /**\n * Return the current time in whichever context is relevant\n */\n _now() {\n return this.context.transport.seconds;\n }\n}\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to [[Time]], but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nfunction TransportTime(value, units) {\n return new TransportTime_TransportTimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=TransportTime.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneWithContext.js\n\n\n\n\n\n\n\n/**\n * The Base class for all nodes that have an AudioContext.\n */\nclass ToneWithContext_ToneWithContext extends Tone {\n constructor() {\n super();\n const options = Defaults_optionsFromArguments(ToneWithContext_ToneWithContext.getDefaults(), arguments, ["context"]);\n if (this.defaultContext) {\n this.context = this.defaultContext;\n }\n else {\n this.context = options.context;\n }\n }\n static getDefaults() {\n return {\n context: Global_getContext(),\n };\n }\n /**\n * Return the current time of the Context clock plus the lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.now());\n * }, 100);\n */\n now() {\n return this.context.currentTime + this.context.lookAhead;\n }\n /**\n * Return the current time of the Context clock without any lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.immediate());\n * }, 100);\n */\n immediate() {\n return this.context.currentTime;\n }\n /**\n * The duration in seconds of one sample.\n * @example\n * console.log(Tone.Transport.sampleTime);\n */\n get sampleTime() {\n return 1 / this.context.sampleRate;\n }\n /**\n * The number of seconds of 1 processing block (128 samples)\n * @example\n * console.log(Tone.Destination.blockTime);\n */\n get blockTime() {\n return 128 / this.context.sampleRate;\n }\n /**\n * Convert the incoming time to seconds.\n * This is calculated against the current [[Tone.Transport]] bpm\n * @example\n * const gain = new Tone.Gain();\n * setInterval(() => console.log(gain.toSeconds("4n")), 100);\n * // ramp the tempo to 60 bpm over 30 seconds\n * Tone.getTransport().bpm.rampTo(60, 30);\n */\n toSeconds(time) {\n return new TimeClass(this.context, time).toSeconds();\n }\n /**\n * Convert the input to a frequency number\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toFrequency("4n"));\n */\n toFrequency(freq) {\n return new Frequency_FrequencyClass(this.context, freq).toFrequency();\n }\n /**\n * Convert the input time into ticks\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toTicks("4n"));\n */\n toTicks(time) {\n return new TransportTime_TransportTimeClass(this.context, time).toTicks();\n }\n //-------------------------------------\n // \tGET/SET\n //-------------------------------------\n /**\n * Get a subset of the properties which are in the partial props\n */\n _getPartialProperties(props) {\n const options = this.get();\n // remove attributes from the prop that are not in the partial\n Object.keys(options).forEach(name => {\n if (TypeCheck_isUndef(props[name])) {\n delete options[name];\n }\n });\n return options;\n }\n /**\n * Get the object\'s attributes.\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.get());\n */\n get() {\n const defaults = getDefaultsFromInstance(this);\n Object.keys(defaults).forEach(attribute => {\n if (Reflect.has(this, attribute)) {\n const member = this[attribute];\n if (TypeCheck_isDefined(member) && TypeCheck_isDefined(member.value) && TypeCheck_isDefined(member.setValueAtTime)) {\n defaults[attribute] = member.value;\n }\n else if (member instanceof ToneWithContext_ToneWithContext) {\n defaults[attribute] = member._getPartialProperties(defaults[attribute]);\n // otherwise make sure it\'s a serializable type\n }\n else if (TypeCheck_isArray(member) || TypeCheck_isNumber(member) || TypeCheck_isString(member) || TypeCheck_isBoolean(member)) {\n defaults[attribute] = member;\n }\n else {\n // remove all undefined and unserializable attributes\n delete defaults[attribute];\n }\n }\n });\n return defaults;\n }\n /**\n * Set multiple properties at once with an object.\n * @example\n * const filter = new Tone.Filter().toDestination();\n * // set values using an object\n * filter.set({\n * \tfrequency: "C6",\n * \ttype: "highpass"\n * });\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/Analogsynth_octaves_highmid.mp3").connect(filter);\n * player.autostart = true;\n */\n set(props) {\n Object.keys(props).forEach(attribute => {\n if (Reflect.has(this, attribute) && TypeCheck_isDefined(this[attribute])) {\n if (this[attribute] && TypeCheck_isDefined(this[attribute].value) && TypeCheck_isDefined(this[attribute].setValueAtTime)) {\n // small optimization\n if (this[attribute].value !== props[attribute]) {\n this[attribute].value = props[attribute];\n }\n }\n else if (this[attribute] instanceof ToneWithContext_ToneWithContext) {\n this[attribute].set(props[attribute]);\n }\n else {\n this[attribute] = props[attribute];\n }\n }\n });\n return this;\n }\n}\n//# sourceMappingURL=ToneWithContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/StateTimeline.js\n\n\n/**\n * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)`\n * @param initial The initial state of the StateTimeline. Defaults to `undefined`\n */\nclass StateTimeline_StateTimeline extends Timeline {\n constructor(initial = "stopped") {\n super();\n this.name = "StateTimeline";\n this._initial = initial;\n this.setStateAtTime(this._initial, 0);\n }\n /**\n * Returns the scheduled state scheduled before or at\n * the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n */\n getValueAtTime(time) {\n const event = this.get(time);\n if (event !== null) {\n return event.state;\n }\n else {\n return this._initial;\n }\n }\n /**\n * Add a state to the timeline.\n * @param state The name of the state to set.\n * @param time The time to query.\n * @param options Any additional options that are needed in the timeline.\n */\n setStateAtTime(state, time, options) {\n Debug_assertRange(time, 0);\n this.add(Object.assign({}, options, {\n state,\n time,\n }));\n return this;\n }\n /**\n * Return the event before the time with the given state\n * @param state The state to look for\n * @param time When to check before\n * @return The event with the given state before the time\n */\n getLastState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n for (let i = index; i >= 0; i--) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n /**\n * Return the event after the time with the given state\n * @param state The state to look for\n * @param time When to check from\n * @return The event with the given state after the time\n */\n getNextState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n if (index !== -1) {\n for (let i = index; i < this._timeline.length; i++) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n }\n}\n//# sourceMappingURL=StateTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Param.js\n\n\n\n\n\n\n\n\n/**\n * Param wraps the native Web Audio\'s AudioParam to provide\n * additional unit conversion functionality. It also\n * serves as a base-class for classes which have a single,\n * automatable parameter.\n * @category Core\n */\nclass Param_Param extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]));\n this.name = "Param";\n this.overridden = false;\n /**\n * The minimum output value\n */\n this._minOutput = 1e-7;\n const options = Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]);\n Debug_assert(TypeCheck_isDefined(options.param) &&\n (isAudioParam(options.param) || options.param instanceof Param_Param), "param must be an AudioParam");\n while (!isAudioParam(options.param)) {\n options.param = options.param._param;\n }\n this._swappable = TypeCheck_isDefined(options.swappable) ? options.swappable : false;\n if (this._swappable) {\n this.input = this.context.createGain();\n // initialize\n this._param = options.param;\n this.input.connect(this._param);\n }\n else {\n this._param = this.input = options.param;\n }\n this._events = new Timeline(1000);\n this._initialValue = this._param.defaultValue;\n this.units = options.units;\n this.convert = options.convert;\n this._minValue = options.minValue;\n this._maxValue = options.maxValue;\n // if the value is defined, set it immediately\n if (TypeCheck_isDefined(options.value) && options.value !== this._toType(this._initialValue)) {\n this.setValueAtTime(options.value, 0);\n }\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n convert: true,\n units: "number",\n });\n }\n get value() {\n const now = this.now();\n return this.getValueAtTime(now);\n }\n set value(value) {\n this.cancelScheduledValues(this.now());\n this.setValueAtTime(value, this.now());\n }\n get minValue() {\n // if it\'s not the default minValue, return it\n if (TypeCheck_isDefined(this._minValue)) {\n return this._minValue;\n }\n else if (this.units === "time" || this.units === "frequency" ||\n this.units === "normalRange" || this.units === "positive" ||\n this.units === "transportTime" || this.units === "ticks" ||\n this.units === "bpm" || this.units === "hertz" || this.units === "samples") {\n return 0;\n }\n else if (this.units === "audioRange") {\n return -1;\n }\n else if (this.units === "decibels") {\n return -Infinity;\n }\n else {\n return this._param.minValue;\n }\n }\n get maxValue() {\n if (TypeCheck_isDefined(this._maxValue)) {\n return this._maxValue;\n }\n else if (this.units === "normalRange" ||\n this.units === "audioRange") {\n return 1;\n }\n else {\n return this._param.maxValue;\n }\n }\n /**\n * Type guard based on the unit name\n */\n _is(arg, type) {\n return this.units === type;\n }\n /**\n * Make sure the value is always in the defined range\n */\n _assertRange(value) {\n if (TypeCheck_isDefined(this.maxValue) && TypeCheck_isDefined(this.minValue)) {\n Debug_assertRange(value, this._fromType(this.minValue), this._fromType(this.maxValue));\n }\n return value;\n }\n /**\n * Convert the given value from the type specified by Param.units\n * into the destination value (such as Gain or Frequency).\n */\n _fromType(val) {\n if (this.convert && !this.overridden) {\n if (this._is(val, "time")) {\n return this.toSeconds(val);\n }\n else if (this._is(val, "decibels")) {\n return Conversions_dbToGain(val);\n }\n else if (this._is(val, "frequency")) {\n return this.toFrequency(val);\n }\n else {\n return val;\n }\n }\n else if (this.overridden) {\n // if it\'s overridden, should only schedule 0s\n return 0;\n }\n else {\n return val;\n }\n }\n /**\n * Convert the parameters value into the units specified by Param.units.\n */\n _toType(val) {\n if (this.convert && this.units === "decibels") {\n return Conversions_gainToDb(val);\n }\n else {\n return val;\n }\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // all docs are generated from ParamInterface.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n const numericValue = this._fromType(value);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(time)}`);\n this._assertRange(numericValue);\n this.log(this.units, "setValueAtTime", value, computedTime);\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: numericValue,\n });\n this._param.setValueAtTime(numericValue, computedTime);\n return this;\n }\n getValueAtTime(time) {\n const computedTime = Math.max(this.toSeconds(time), 0);\n const after = this._events.getAfter(computedTime);\n const before = this._events.get(computedTime);\n let value = this._initialValue;\n // if it was set by\n if (before === null) {\n value = this._initialValue;\n }\n else if (before.type === "setTargetAtTime" && (after === null || after.type === "setValueAtTime")) {\n const previous = this._events.getBefore(before.time);\n let previousVal;\n if (previous === null) {\n previousVal = this._initialValue;\n }\n else {\n previousVal = previous.value;\n }\n if (before.type === "setTargetAtTime") {\n value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, computedTime);\n }\n }\n else if (after === null) {\n value = before.value;\n }\n else if (after.type === "linearRampToValueAtTime" || after.type === "exponentialRampToValueAtTime") {\n let beforeValue = before.value;\n if (before.type === "setTargetAtTime") {\n const previous = this._events.getBefore(before.time);\n if (previous === null) {\n beforeValue = this._initialValue;\n }\n else {\n beforeValue = previous.value;\n }\n }\n if (after.type === "linearRampToValueAtTime") {\n value = this._linearInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n else {\n value = this._exponentialInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n }\n else {\n value = before.value;\n }\n return this._toType(value);\n }\n setRampPoint(time) {\n time = this.toSeconds(time);\n let currentVal = this.getValueAtTime(time);\n this.cancelAndHoldAtTime(time);\n if (this._fromType(currentVal) === 0) {\n currentVal = this._toType(this._minOutput);\n }\n this.setValueAtTime(currentVal, time);\n return this;\n }\n linearRampToValueAtTime(value, endTime) {\n const numericValue = this._fromType(value);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to linearRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n this._assertRange(numericValue);\n this._events.add({\n time: computedTime,\n type: "linearRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "linearRampToValueAtTime", value, computedTime);\n this._param.linearRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, endTime) {\n let numericValue = this._fromType(value);\n // the value can\'t be 0\n numericValue = EQ(numericValue, 0) ? this._minOutput : numericValue;\n this._assertRange(numericValue);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to exponentialRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n // store the event\n this._events.add({\n time: computedTime,\n type: "exponentialRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "exponentialRampToValueAtTime", value, computedTime);\n this._param.exponentialRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialApproachValueAtTime(value, startTime, rampTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n time = this.toSeconds(time);\n rampTime = this.toSeconds(rampTime);\n const timeConstant = Math.log(rampTime + 1) / Math.log(200);\n this.setTargetAtTime(value, time, timeConstant);\n // at 90% start a linear ramp to the final value\n this.cancelAndHoldAtTime(time + rampTime * 0.9);\n this.linearRampToValueAtTime(value, time + rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const numericValue = this._fromType(value);\n // The value will never be able to approach without timeConstant > 0.\n Debug_assert(isFinite(timeConstant) && timeConstant > 0, "timeConstant must be a number greater than 0");\n const computedTime = this.toSeconds(startTime);\n this._assertRange(numericValue);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setTargetAtTime: ${JSON.stringify(value)}, ${JSON.stringify(startTime)}`);\n this._events.add({\n constant: timeConstant,\n time: computedTime,\n type: "setTargetAtTime",\n value: numericValue,\n });\n this.log(this.units, "setTargetAtTime", value, computedTime, timeConstant);\n this._param.setTargetAtTime(numericValue, computedTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling = 1) {\n duration = this.toSeconds(duration);\n startTime = this.toSeconds(startTime);\n const startingValue = this._fromType(values[0]) * scaling;\n this.setValueAtTime(this._toType(startingValue), startTime);\n const segTime = duration / (values.length - 1);\n for (let i = 1; i < values.length; i++) {\n const numericValue = this._fromType(values[i]) * scaling;\n this.linearRampToValueAtTime(this._toType(numericValue), startTime + i * segTime);\n }\n return this;\n }\n cancelScheduledValues(time) {\n const computedTime = this.toSeconds(time);\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelScheduledValues: ${JSON.stringify(time)}`);\n this._events.cancel(computedTime);\n this._param.cancelScheduledValues(computedTime);\n this.log(this.units, "cancelScheduledValues", computedTime);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = this.toSeconds(time);\n const valueAtTime = this._fromType(this.getValueAtTime(computedTime));\n // remove the schedule events\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelAndHoldAtTime: ${JSON.stringify(time)}`);\n this.log(this.units, "cancelAndHoldAtTime", computedTime, "value=" + valueAtTime);\n // if there is an event at the given computedTime\n // and that even is not a "set"\n const before = this._events.get(computedTime);\n const after = this._events.getAfter(computedTime);\n if (before && EQ(before.time, computedTime)) {\n // remove everything after\n if (after) {\n this._param.cancelScheduledValues(after.time);\n this._events.cancel(after.time);\n }\n else {\n this._param.cancelAndHoldAtTime(computedTime);\n this._events.cancel(computedTime + this.sampleTime);\n }\n }\n else if (after) {\n this._param.cancelScheduledValues(after.time);\n // cancel the next event(s)\n this._events.cancel(after.time);\n if (after.type === "linearRampToValueAtTime") {\n this.linearRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n else if (after.type === "exponentialRampToValueAtTime") {\n this.exponentialRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n }\n // set the value at the given time\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: valueAtTime,\n });\n this._param.setValueAtTime(valueAtTime, computedTime);\n return this;\n }\n rampTo(value, rampTime = 0.1, startTime) {\n if (this.units === "frequency" || this.units === "bpm" || this.units === "decibels") {\n this.exponentialRampTo(value, rampTime, startTime);\n }\n else {\n this.linearRampTo(value, rampTime, startTime);\n }\n return this;\n }\n /**\n * Apply all of the previously scheduled events to the passed in Param or AudioParam.\n * The applied values will start at the context\'s current time and schedule\n * all of the events which are scheduled on this Param onto the passed in param.\n */\n apply(param) {\n const now = this.context.currentTime;\n // set the param\'s value at the current time and schedule everything else\n param.setValueAtTime(this.getValueAtTime(now), now);\n // if the previous event was a curve, then set the rest of it\n const previousEvent = this._events.get(now);\n if (previousEvent && previousEvent.type === "setTargetAtTime") {\n // approx it until the next event with linear ramps\n const nextEvent = this._events.getAfter(previousEvent.time);\n // or for 2 seconds if there is no event\n const endTime = nextEvent ? nextEvent.time : now + 2;\n const subdivisions = (endTime - now) / 10;\n for (let i = now; i < endTime; i += subdivisions) {\n param.linearRampToValueAtTime(this.getValueAtTime(i), i);\n }\n }\n this._events.forEachAfter(this.context.currentTime, event => {\n if (event.type === "cancelScheduledValues") {\n param.cancelScheduledValues(event.time);\n }\n else if (event.type === "setTargetAtTime") {\n param.setTargetAtTime(event.value, event.time, event.constant);\n }\n else {\n param[event.type](event.value, event.time);\n }\n });\n return this;\n }\n /**\n * Replace the Param\'s internal AudioParam. Will apply scheduled curves\n * onto the parameter and replace the connections.\n */\n setParam(param) {\n Debug_assert(this._swappable, "The Param must be assigned as \'swappable\' in the constructor");\n const input = this.input;\n input.disconnect(this._param);\n this.apply(param);\n this._param = param;\n input.connect(this._param);\n return this;\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n return this;\n }\n get defaultValue() {\n return this._toType(this._param.defaultValue);\n }\n //-------------------------------------\n // \tAUTOMATION CURVE CALCULATIONS\n // \tMIT License, copyright (c) 2014 Jordan Santell\n //-------------------------------------\n // Calculates the the value along the curve produced by setTargetAtTime\n _exponentialApproach(t0, v0, v1, timeConstant, t) {\n return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n }\n // Calculates the the value along the curve produced by linearRampToValueAtTime\n _linearInterpolate(t0, v0, t1, v1, t) {\n return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n }\n // Calculates the the value along the curve produced by exponentialRampToValueAtTime\n _exponentialInterpolate(t0, v0, t1, v1, t) {\n return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n }\n}\n//# sourceMappingURL=Param.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioNode.js\n\n\n\n\n\n/**\n * ToneAudioNode is the base class for classes which process audio.\n */\nclass ToneAudioNode_ToneAudioNode extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n /**\n * The name of the class\n */\n this.name = "ToneAudioNode";\n /**\n * List all of the node that must be set to match the ChannelProperties\n */\n this._internalChannels = [];\n }\n /**\n * The number of inputs feeding into the AudioNode.\n * For source nodes, this will be 0.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfInputs);\n */\n get numberOfInputs() {\n if (TypeCheck_isDefined(this.input)) {\n if (isAudioParam(this.input) || this.input instanceof Param_Param) {\n return 1;\n }\n else {\n return this.input.numberOfInputs;\n }\n }\n else {\n return 0;\n }\n }\n /**\n * The number of outputs of the AudioNode.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfOutputs);\n */\n get numberOfOutputs() {\n if (TypeCheck_isDefined(this.output)) {\n return this.output.numberOfOutputs;\n }\n else {\n return 0;\n }\n }\n //-------------------------------------\n // AUDIO PROPERTIES\n //-------------------------------------\n /**\n * Used to decide which nodes to get/set properties on\n */\n _isAudioNode(node) {\n return TypeCheck_isDefined(node) && (node instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(node));\n }\n /**\n * Get all of the audio nodes (either internal or input/output) which together\n * make up how the class node responds to channel input/output\n */\n _getInternalNodes() {\n const nodeList = this._internalChannels.slice(0);\n if (this._isAudioNode(this.input)) {\n nodeList.push(this.input);\n }\n if (this._isAudioNode(this.output)) {\n if (this.input !== this.output) {\n nodeList.push(this.output);\n }\n }\n return nodeList;\n }\n /**\n * Set the audio options for this node such as channelInterpretation\n * channelCount, etc.\n * @param options\n */\n _setChannelProperties(options) {\n const nodeList = this._getInternalNodes();\n nodeList.forEach(node => {\n node.channelCount = options.channelCount;\n node.channelCountMode = options.channelCountMode;\n node.channelInterpretation = options.channelInterpretation;\n });\n }\n /**\n * Get the current audio options for this node such as channelInterpretation\n * channelCount, etc.\n */\n _getChannelProperties() {\n const nodeList = this._getInternalNodes();\n Debug_assert(nodeList.length > 0, "ToneAudioNode does not have any internal nodes");\n // use the first node to get properties\n // they should all be the same\n const node = nodeList[0];\n return {\n channelCount: node.channelCount,\n channelCountMode: node.channelCountMode,\n channelInterpretation: node.channelInterpretation,\n };\n }\n /**\n * channelCount is the number of channels used when up-mixing and down-mixing\n * connections to any inputs to the node. The default value is 2 except for\n * specific nodes where its value is specially determined.\n */\n get channelCount() {\n return this._getChannelProperties().channelCount;\n }\n set channelCount(channelCount) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCount }));\n }\n /**\n * channelCountMode determines how channels will be counted when up-mixing and\n * down-mixing connections to any inputs to the node.\n * The default value is "max". This attribute has no effect for nodes with no inputs.\n * * "max" - computedNumberOfChannels is the maximum of the number of channels of all connections to an input. In this mode channelCount is ignored.\n * * "clamped-max" - computedNumberOfChannels is determined as for "max" and then clamped to a maximum value of the given channelCount.\n * * "explicit" - computedNumberOfChannels is the exact value as specified by the channelCount.\n */\n get channelCountMode() {\n return this._getChannelProperties().channelCountMode;\n }\n set channelCountMode(channelCountMode) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCountMode }));\n }\n /**\n * channelInterpretation determines how individual channels will be treated\n * when up-mixing and down-mixing connections to any inputs to the node.\n * The default value is "speakers".\n */\n get channelInterpretation() {\n return this._getChannelProperties().channelInterpretation;\n }\n set channelInterpretation(channelInterpretation) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelInterpretation }));\n }\n //-------------------------------------\n // CONNECTIONS\n //-------------------------------------\n /**\n * connect the output of a ToneAudioNode to an AudioParam, AudioNode, or ToneAudioNode\n * @param destination The output to connect to\n * @param outputNum The output to connect from\n * @param inputNum The input to connect to\n */\n connect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_connect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * @example\n * const osc = new Tone.Oscillator("C2").start();\n * osc.toDestination();\n */\n toDestination() {\n this.connect(this.context.destination);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * See [[toDestination]]\n * @deprecated\n */\n toMaster() {\n Debug_warn("toMaster() has been renamed toDestination()");\n return this.toDestination();\n }\n /**\n * disconnect the output\n */\n disconnect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_disconnect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output of this node to the rest of the nodes in series.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/handdrum-loop.mp3");\n * player.autostart = true;\n * const filter = new Tone.AutoFilter(4).start();\n * const distortion = new Tone.Distortion(0.5);\n * // connect the player to the filter, distortion and then to the master output\n * player.chain(filter, distortion, Tone.Destination);\n */\n chain(...nodes) {\n ToneAudioNode_connectSeries(this, ...nodes);\n return this;\n }\n /**\n * connect the output of this node to the rest of the nodes in parallel.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/conga-rhythm.mp3");\n * player.autostart = true;\n * const pitchShift = new Tone.PitchShift(4).toDestination();\n * const filter = new Tone.Filter("G5").toDestination();\n * // connect a node to the pitch shift and filter in parallel\n * player.fan(pitchShift, filter);\n */\n fan(...nodes) {\n nodes.forEach(node => this.connect(node));\n return this;\n }\n /**\n * Dispose and disconnect\n */\n dispose() {\n super.dispose();\n if (TypeCheck_isDefined(this.input)) {\n if (this.input instanceof ToneAudioNode_ToneAudioNode) {\n this.input.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.input)) {\n this.input.disconnect();\n }\n }\n if (TypeCheck_isDefined(this.output)) {\n if (this.output instanceof ToneAudioNode_ToneAudioNode) {\n this.output.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.output)) {\n this.output.disconnect();\n }\n }\n this._internalChannels = [];\n return this;\n }\n}\n//-------------------------------------\n// CONNECTIONS\n//-------------------------------------\n/**\n * connect together all of the arguments in series\n * @param nodes\n */\nfunction ToneAudioNode_connectSeries(...nodes) {\n const first = nodes.shift();\n nodes.reduce((prev, current) => {\n if (prev instanceof ToneAudioNode_ToneAudioNode) {\n prev.connect(current);\n }\n else if (AdvancedTypeCheck_isAudioNode(prev)) {\n ToneAudioNode_connect(prev, current);\n }\n return current;\n }, first);\n}\n/**\n * Connect two nodes together so that signal flows from the\n * first node to the second. Optionally specify the input and output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_connect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n Debug_assert(TypeCheck_isDefined(srcNode), "Cannot connect from undefined node");\n Debug_assert(TypeCheck_isDefined(dstNode), "Cannot connect to undefined node");\n if (dstNode instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(dstNode)) {\n Debug_assert(dstNode.numberOfInputs > 0, "Cannot connect to node with no inputs");\n }\n Debug_assert(srcNode.numberOfOutputs > 0, "Cannot connect from node with no outputs");\n // resolve the input of the dstNode\n while ((dstNode instanceof ToneAudioNode_ToneAudioNode || dstNode instanceof Param_Param)) {\n if (TypeCheck_isDefined(dstNode.input)) {\n dstNode = dstNode.input;\n }\n }\n while (srcNode instanceof ToneAudioNode_ToneAudioNode) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n // make the connection\n if (isAudioParam(dstNode)) {\n srcNode.connect(dstNode, outputNumber);\n }\n else {\n srcNode.connect(dstNode, outputNumber, inputNumber);\n }\n}\n/**\n * Disconnect a node from all nodes or optionally include a destination node and input/output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_disconnect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n // resolve the destination node\n if (TypeCheck_isDefined(dstNode)) {\n while (dstNode instanceof ToneAudioNode_ToneAudioNode) {\n dstNode = dstNode.input;\n }\n }\n // resolve the src node\n while (!(AdvancedTypeCheck_isAudioNode(srcNode))) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n if (isAudioParam(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber);\n }\n else if (AdvancedTypeCheck_isAudioNode(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber, inputNumber);\n }\n else {\n srcNode.disconnect();\n }\n}\n//# sourceMappingURL=ToneAudioNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Gain.js\n\n\n\n\n/**\n * A thin wrapper around the Native Web Audio GainNode.\n * The GainNode is a basic building block of the Web Audio\n * API and is useful for routing audio and adjusting gains.\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst gainNode = new Tone.Gain(0).toDestination();\n * \tconst osc = new Tone.Oscillator(30).connect(gainNode).start();\n * \tgainNode.gain.rampTo(1, 0.1);\n * \tgainNode.gain.rampTo(0, 0.4, 0.2);\n * }, 0.7, 1);\n */\nclass Gain_Gain extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]));\n this.name = "Gain";\n /**\n * The wrapped GainNode.\n */\n this._gainNode = this.context.createGain();\n // input = output\n this.input = this._gainNode;\n this.output = this._gainNode;\n const options = Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]);\n this.gain = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._gainNode.gain,\n units: options.units,\n value: options.gain,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n Interface_readOnly(this, "gain");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n gain: 1,\n units: "gain",\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/OneShotSource.js\n\n\n\n\n/**\n * Base class for fire-and-forget nodes\n */\nclass OneShotSource extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * The callback to invoke after the\n * source is done playing.\n */\n this.onended = Interface_noOp;\n /**\n * The start time\n */\n this._startTime = -1;\n /**\n * The stop time\n */\n this._stopTime = -1;\n /**\n * The id of the timeout\n */\n this._timeout = -1;\n /**\n * The public output node\n */\n this.output = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output gain node.\n */\n this._gainNode = this.output;\n /**\n * Get the playback state at the given time\n */\n this.getStateAtTime = function (time) {\n const computedTime = this.toSeconds(time);\n if (this._startTime !== -1 &&\n computedTime >= this._startTime &&\n (this._stopTime === -1 || computedTime <= this._stopTime)) {\n return "started";\n }\n else {\n return "stopped";\n }\n };\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n this._curve = options.curve;\n this.onended = options.onended;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n curve: "linear",\n fadeIn: 0,\n fadeOut: 0,\n onended: Interface_noOp,\n });\n }\n /**\n * Start the source at the given time\n * @param time When to start the source\n */\n _startGain(time, gain = 1) {\n Debug_assert(this._startTime === -1, "Source cannot be started more than once");\n // apply a fade in envelope\n const fadeInTime = this.toSeconds(this._fadeIn);\n // record the start time\n this._startTime = time + fadeInTime;\n this._startTime = Math.max(this._startTime, this.context.currentTime);\n // schedule the envelope\n if (fadeInTime > 0) {\n this._gainNode.gain.setValueAtTime(0, time);\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampToValueAtTime(gain, time + fadeInTime);\n }\n else {\n this._gainNode.gain.exponentialApproachValueAtTime(gain, time, fadeInTime);\n }\n }\n else {\n this._gainNode.gain.setValueAtTime(gain, time);\n }\n return this;\n }\n /**\n * Stop the source node at the given time.\n * @param time When to stop the source\n */\n stop(time) {\n this.log("stop", time);\n this._stopGain(this.toSeconds(time));\n return this;\n }\n /**\n * Stop the source at the given time\n * @param time When to stop the source\n */\n _stopGain(time) {\n Debug_assert(this._startTime !== -1, "\'start\' must be called before \'stop\'");\n // cancel the previous stop\n this.cancelStop();\n // the fadeOut time\n const fadeOutTime = this.toSeconds(this._fadeOut);\n // schedule the stop callback\n this._stopTime = this.toSeconds(time) + fadeOutTime;\n this._stopTime = Math.max(this._stopTime, this.context.currentTime);\n if (fadeOutTime > 0) {\n // start the fade out curve at the given time\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampTo(0, fadeOutTime, time);\n }\n else {\n this._gainNode.gain.targetRampTo(0, fadeOutTime, time);\n }\n }\n else {\n // stop any ongoing ramps, and set the value to 0\n this._gainNode.gain.cancelAndHoldAtTime(time);\n this._gainNode.gain.setValueAtTime(0, time);\n }\n this.context.clearTimeout(this._timeout);\n this._timeout = this.context.setTimeout(() => {\n // allow additional time for the exponential curve to fully decay\n const additionalTail = this._curve === "exponential" ? fadeOutTime * 2 : 0;\n this._stopSource(this.now() + additionalTail);\n this._onended();\n }, this._stopTime - this.context.currentTime);\n return this;\n }\n /**\n * Invoke the onended callback\n */\n _onended() {\n if (this.onended !== Interface_noOp) {\n this.onended(this);\n // overwrite onended to make sure it only is called once\n this.onended = Interface_noOp;\n // dispose when it\'s ended to free up for garbage collection only in the online context\n if (!this.context.isOffline) {\n const disposeCallback = () => this.dispose();\n // @ts-ignore\n if (typeof window.requestIdleCallback !== "undefined") {\n // @ts-ignore\n window.requestIdleCallback(disposeCallback);\n }\n else {\n setTimeout(disposeCallback, 1000);\n }\n }\n }\n }\n /**\n * Get the playback state at the current time\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Cancel a scheduled stop event\n */\n cancelStop() {\n this.log("cancelStop");\n Debug_assert(this._startTime !== -1, "Source is not started");\n // cancel the stop envelope\n this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime);\n this.context.clearTimeout(this._timeout);\n this._stopTime = -1;\n return this;\n }\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OneShotSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ToneConstantSource.js\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget ConstantSource.\n * Adds the ability to reschedule the stop method.\n * @category Signal\n */\nclass ToneConstantSource_ToneConstantSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]));\n this.name = "ToneConstantSource";\n /**\n * The signal generator\n */\n this._source = this.context.createConstantSource();\n const options = Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this.offset = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._source.offset,\n units: options.units,\n value: options.offset,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n convert: true,\n offset: 1,\n units: "number",\n });\n }\n /**\n * Start the source node at the given time\n * @param time When to start the source\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._source.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._source.stop(time);\n }\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._source.disconnect();\n this.offset.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneConstantSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Signal.js\n\n\n\n\n\n\n/**\n * A signal is an audio-rate value. Tone.Signal is a core component of the library.\n * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n * has all of the methods available to native Web Audio\n * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n * as well as additional conveniences. Read more about working with signals\n * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a scheduleable signal which can be connected to control an AudioParam or another Signal\n * const signal = new Tone.Signal({\n * \tvalue: "C4",\n * \tunits: "frequency"\n * }).connect(osc.frequency);\n * // the scheduled ramp controls the connected signal\n * signal.rampTo("C2", 4, "+0.5");\n * @category Signal\n */\nclass Signal_Signal extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "Signal";\n /**\n * Indicates if the value should be overridden on connection.\n */\n this.override = true;\n const options = Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]);\n this.output = this._constantSource = new ToneConstantSource_ToneConstantSource({\n context: this.context,\n convert: options.convert,\n offset: options.value,\n units: options.units,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this._constantSource.start(0);\n this.input = this._param = this._constantSource.offset;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n units: "number",\n value: 0,\n });\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n // start it only when connected to something\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n this._constantSource.dispose();\n return this;\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // just a proxy for the ConstantSourceNode\'s offset AudioParam\n // all docs are generated from AbstractParam.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n this._param.setValueAtTime(value, time);\n return this;\n }\n getValueAtTime(time) {\n return this._param.getValueAtTime(time);\n }\n setRampPoint(time) {\n this._param.setRampPoint(time);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n this._param.linearRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n this._param.exponentialRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n this._param.exponentialRampTo(value, rampTime, startTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n this._param.linearRampTo(value, rampTime, startTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n this._param.targetRampTo(value, rampTime, startTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n this._param.exponentialApproachValueAtTime(value, time, rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n this._param.setTargetAtTime(value, startTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n this._param.setValueCurveAtTime(values, startTime, duration, scaling);\n return this;\n }\n cancelScheduledValues(time) {\n this._param.cancelScheduledValues(time);\n return this;\n }\n cancelAndHoldAtTime(time) {\n this._param.cancelAndHoldAtTime(time);\n return this;\n }\n rampTo(value, rampTime, startTime) {\n this._param.rampTo(value, rampTime, startTime);\n return this;\n }\n get value() {\n return this._param.value;\n }\n set value(value) {\n this._param.value = value;\n }\n get convert() {\n return this._param.convert;\n }\n set convert(convert) {\n this._param.convert = convert;\n }\n get units() {\n return this._param.units;\n }\n get overridden() {\n return this._param.overridden;\n }\n set overridden(overridden) {\n this._param.overridden = overridden;\n }\n get maxValue() {\n return this._param.maxValue;\n }\n get minValue() {\n return this._param.minValue;\n }\n /**\n * See [[Param.apply]].\n */\n apply(param) {\n this._param.apply(param);\n return this;\n }\n}\n/**\n * When connecting from a signal, it\'s necessary to zero out the node destination\n * node if that node is also a signal. If the destination is not 0, then the values\n * will be summed. This method insures that the output of the destination signal will\n * be the same as the source signal, making the destination signal a pass through node.\n * @param signal The output signal to connect from\n * @param destination the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\nfunction Signal_connectSignal(signal, destination, outputNum, inputNum) {\n if (destination instanceof Param_Param || isAudioParam(destination) ||\n (destination instanceof Signal_Signal && destination.override)) {\n // cancel changes\n destination.cancelScheduledValues(0);\n // reset the value\n destination.setValueAtTime(0, 0);\n // mark the value as overridden\n if (destination instanceof Signal_Signal) {\n destination.overridden = true;\n }\n }\n ToneAudioNode_connect(signal, destination, outputNum, inputNum);\n}\n//# sourceMappingURL=Signal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickParam.js\n\n\n\n\n/**\n * A Param class just for computing ticks. Similar to the [[Param]] class,\n * but offers conversion to BPM values as well as ability to compute tick\n * duration and elapsed ticks\n */\nclass TickParam extends Param_Param {\n constructor() {\n super(Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]));\n this.name = "TickParam";\n /**\n * The timeline which tracks all of the automations.\n */\n this._events = new Timeline(Infinity);\n /**\n * The internal holder for the multiplier value\n */\n this._multiplier = 1;\n const options = Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]);\n // set the multiplier\n this._multiplier = options.multiplier;\n // clear the ticks from the beginning\n this._events.cancel(0);\n // set an initial event\n this._events.add({\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: this._fromType(options.value),\n });\n this.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Param_Param.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n setTargetAtTime(value, time, constant) {\n // approximate it with multiple linear ramps\n time = this.toSeconds(time);\n this.setRampPoint(time);\n const computedValue = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n const segments = Math.round(Math.max(1 / constant, 1));\n for (let i = 0; i <= segments; i++) {\n const segTime = constant * i + time;\n const rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, computedValue, constant, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.setValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.linearRampToValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n // aproximate it with multiple linear ramps\n time = this.toSeconds(time);\n const computedVal = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n // approx 10 segments per second\n const segments = Math.round(Math.max((time - prevEvent.time) * 10, 1));\n const segmentDur = ((time - prevEvent.time) / segments);\n for (let i = 0; i <= segments; i++) {\n const segTime = segmentDur * i + prevEvent.time;\n const rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, computedVal, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param event The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n _getTicksUntilEvent(event, time) {\n if (event === null) {\n event = {\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: 0,\n };\n }\n else if (TypeCheck_isUndef(event.ticks)) {\n const previousEvent = this._events.previousEvent(event);\n event.ticks = this._getTicksUntilEvent(previousEvent, event.time);\n }\n const val0 = this._fromType(this.getValueAtTime(event.time));\n let val1 = this._fromType(this.getValueAtTime(time));\n // if it\'s right on the line, take the previous value\n const onTheLineEvent = this._events.get(time);\n if (onTheLineEvent && onTheLineEvent.time === time && onTheLineEvent.type === "setValueAtTime") {\n val1 = this._fromType(this.getValueAtTime(time - this.sampleTime));\n }\n return 0.5 * (time - event.time) * (val0 + val1) + event.ticks;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param time The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const event = this._events.get(computedTime);\n return Math.max(this._getTicksUntilEvent(event, computedTime), 0);\n }\n /**\n * Return the elapsed time of the number of ticks from the given time\n * @param ticks The number of ticks to calculate\n * @param time The time to get the next tick from\n * @return The duration of the number of ticks from the given time in seconds\n */\n getDurationOfTicks(ticks, time) {\n const computedTime = this.toSeconds(time);\n const currentTick = this.getTicksAtTime(time);\n return this.getTimeOfTick(currentTick + ticks) - computedTime;\n }\n /**\n * Given a tick, returns the time that tick occurs at.\n * @return The time that the tick occurs.\n */\n getTimeOfTick(tick) {\n const before = this._events.get(tick, "ticks");\n const after = this._events.getAfter(tick, "ticks");\n if (before && before.ticks === tick) {\n return before.time;\n }\n else if (before && after &&\n after.type === "linearRampToValueAtTime" &&\n before.value !== after.value) {\n const val0 = this._fromType(this.getValueAtTime(before.time));\n const val1 = this._fromType(this.getValueAtTime(after.time));\n const delta = (val1 - val0) / (after.time - before.time);\n const k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick));\n const sol1 = (-val0 + k) / delta;\n const sol2 = (-val0 - k) / delta;\n return (sol1 > 0 ? sol1 : sol2) + before.time;\n }\n else if (before) {\n if (before.value === 0) {\n return Infinity;\n }\n else {\n return before.time + (tick - before.ticks) / before.value;\n }\n }\n else {\n return tick / this._initialValue;\n }\n }\n /**\n * Convert some number of ticks their the duration in seconds accounting\n * for any automation curves starting at the given time.\n * @param ticks The number of ticks to convert to seconds.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in seconds of the ticks.\n */\n ticksToTime(ticks, when) {\n return this.getDurationOfTicks(ticks, when);\n }\n /**\n * The inverse of [[ticksToTime]]. Convert a duration in\n * seconds to the corresponding number of ticks accounting for any\n * automation curves starting at the given time.\n * @param duration The time interval to convert to ticks.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in ticks.\n */\n timeToTicks(duration, when) {\n const computedTime = this.toSeconds(when);\n const computedDuration = this.toSeconds(duration);\n const startTicks = this.getTicksAtTime(computedTime);\n const endTicks = this.getTicksAtTime(computedTime + computedDuration);\n return endTicks - startTicks;\n }\n /**\n * Convert from the type when the unit value is BPM\n */\n _fromType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return 1 / (60 / val / this.multiplier);\n }\n else {\n return super._fromType(val);\n }\n }\n /**\n * Special case of type conversion where the units === "bpm"\n */\n _toType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return (val / this.multiplier) * 60;\n }\n else {\n return super._toType(val);\n }\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._multiplier;\n }\n set multiplier(m) {\n // get and reset the current value with the new multiplier\n // might be necessary to clear all the previous values\n const currentVal = this.value;\n this._multiplier = m;\n this.cancelScheduledValues(0);\n this.setValueAtTime(currentVal, 0);\n }\n}\n//# sourceMappingURL=TickParam.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSignal.js\n\n\n\n/**\n * TickSignal extends Tone.Signal, but adds the capability\n * to calculate the number of elapsed ticks. exponential and target curves\n * are approximated with multiple linear ramps.\n *\n * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos,\n * for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf)\n * describing integrating timing functions for tempo calculations.\n */\nclass TickSignal extends Signal_Signal {\n constructor() {\n super(Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]));\n this.name = "TickSignal";\n const options = Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]);\n this.input = this._param = new TickParam({\n context: this.context,\n convert: options.convert,\n multiplier: options.multiplier,\n param: this._constantSource.offset,\n units: options.units,\n value: options.value,\n });\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n ticksToTime(ticks, when) {\n return this._param.ticksToTime(ticks, when);\n }\n timeToTicks(duration, when) {\n return this._param.timeToTicks(duration, when);\n }\n getTimeOfTick(tick) {\n return this._param.getTimeOfTick(tick);\n }\n getDurationOfTicks(ticks, time) {\n return this._param.getDurationOfTicks(ticks, time);\n }\n getTicksAtTime(time) {\n return this._param.getTicksAtTime(time);\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._param.multiplier;\n }\n set multiplier(m) {\n this._param.multiplier = m;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSource.js\n\n\n\n\n\n\n\n\n/**\n * Uses [TickSignal](TickSignal) to track elapsed ticks with complex automation curves.\n */\nclass TickSource extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]));\n this.name = "TickSource";\n /**\n * The state timeline\n */\n this._state = new StateTimeline_StateTimeline();\n /**\n * The offset values of the ticks\n */\n this._tickOffset = new Timeline();\n const options = Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]);\n this.frequency = new TickSignal({\n context: this.context,\n units: options.units,\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n // set the initial state\n this._state.setStateAtTime("stopped", 0);\n // add the first event\n this.setTicksAtTime(0, 0);\n }\n static getDefaults() {\n return Object.assign({\n frequency: 1,\n units: "hertz",\n }, ToneWithContext_ToneWithContext.getDefaults());\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset The number of ticks to start the source at\n */\n start(time, offset) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n if (TypeCheck_isDefined(offset)) {\n this.setTicksAtTime(offset, computedTime);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n // cancel the previous stop\n if (this._state.getValueAtTime(computedTime) === "stopped") {\n const event = this._state.get(computedTime);\n if (event && event.time > 0) {\n this._tickOffset.cancel(event.time);\n this._state.cancel(event.time);\n }\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this.setTicksAtTime(0, computedTime);\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n }\n return this;\n }\n /**\n * Cancel start/stop/pause and setTickAtTime events scheduled after the given time.\n * @param time When to clear the events after\n */\n cancel(time) {\n time = this.toSeconds(time);\n this._state.cancel(time);\n this._tickOffset.cancel(time);\n return this;\n }\n /**\n * Get the elapsed ticks at the given time\n * @param time When to get the tick value\n * @return The number of ticks\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", computedTime);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time: computedTime };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedTicks = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, computedTime + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedTicks = offsetEvent.ticks;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime);\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedTicks;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked. Returns -1 when stopped.\n */\n get ticks() {\n return this.getTicksAtTime(this.now());\n }\n set ticks(t) {\n this.setTicksAtTime(t, this.now());\n }\n /**\n * The time since ticks=0 that the TickSource has been running. Accounts\n * for tempo curves\n */\n get seconds() {\n return this.getSecondsAtTime(this.now());\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this.frequency.timeToTicks(s, now);\n this.setTicksAtTime(ticks, now);\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n time = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", time);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedSeconds = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, time + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedSeconds = offsetEvent.seconds;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedSeconds += e.time - periodStartTime;\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedSeconds;\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n time = this.toSeconds(time);\n this._tickOffset.cancel(time);\n this._tickOffset.add({\n seconds: this.frequency.getDurationOfTicks(ticks, time),\n ticks,\n time,\n });\n return this;\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n */\n getStateAtTime(time) {\n time = this.toSeconds(time);\n return this._state.getValueAtTime(time);\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n const offset = this._tickOffset.get(before);\n const event = this._state.get(before);\n const startTime = Math.max(offset.time, event.time);\n const absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks;\n return this.frequency.getTimeOfTick(absoluteTicks);\n }\n /**\n * Invoke the callback event at all scheduled ticks between the\n * start time and the end time\n * @param startTime The beginning of the search range\n * @param endTime The end of the search range\n * @param callback The callback to invoke with each tick\n */\n forEachTickBetween(startTime, endTime, callback) {\n // only iterate through the sections where it is "started"\n let lastStateEvent = this._state.get(startTime);\n this._state.forEachBetween(startTime, endTime, event => {\n if (lastStateEvent && lastStateEvent.state === "started" && event.state !== "started") {\n this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback);\n }\n lastStateEvent = event;\n });\n let error = null;\n if (lastStateEvent && lastStateEvent.state === "started") {\n const maxStartTime = Math.max(lastStateEvent.time, startTime);\n // figure out the difference between the frequency ticks and the\n const startTicks = this.frequency.getTicksAtTime(maxStartTime);\n const ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time);\n const diff = startTicks - ticksAtStart;\n let offset = Math.ceil(diff) - diff;\n // guard against floating point issues\n offset = EQ(offset, 1) ? 0 : offset;\n let nextTickTime = this.frequency.getTimeOfTick(startTicks + offset);\n while (nextTickTime < endTime) {\n try {\n callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime)));\n }\n catch (e) {\n error = e;\n break;\n }\n nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime);\n }\n }\n if (error) {\n throw error;\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._state.dispose();\n this._tickOffset.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Clock.js\n\n\n\n\n\n\n\n/**\n * A sample accurate clock which provides a callback at the given rate.\n * While the callback is not sample-accurate (it is still susceptible to\n * loose JS timing), the time passed in as the argument to the callback\n * is precise. For most applications, it is better to use Tone.Transport\n * instead of the Clock by itself since you can synchronize multiple callbacks.\n * @example\n * // the callback will be invoked approximately once a second\n * // and will print the time exactly once a second apart.\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * @category Core\n */\nclass Clock_Clock extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]));\n this.name = "Clock";\n /**\n * The callback function to invoke at the scheduled tick.\n */\n this.callback = Interface_noOp;\n /**\n * The last time the loop callback was invoked\n */\n this._lastUpdate = 0;\n /**\n * Keep track of the playback state\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * Context bound reference to the _loop method\n * This is necessary to remove the event in the end.\n */\n this._boundLoop = this._loop.bind(this);\n const options = Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]);\n this.callback = options.callback;\n this._tickSource = new TickSource({\n context: this.context,\n frequency: options.frequency,\n units: options.units,\n });\n this._lastUpdate = 0;\n this.frequency = this._tickSource.frequency;\n Interface_readOnly(this, "frequency");\n // add an initial state\n this._state.setStateAtTime("stopped", 0);\n // bind a callback to the worker thread\n this.context.on("tick", this._boundLoop);\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n callback: Interface_noOp,\n frequency: 1,\n units: "hertz",\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this._state.getValueAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset Where the tick counter starts counting from.\n */\n start(time, offset) {\n // make sure the context is running\n assertContextRunning(this.context);\n // start the loop\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n this._tickSource.start(computedTime, offset);\n if (computedTime < this._lastUpdate) {\n this.emit("start", computedTime, offset);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n * @example\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * // stop the clock after 10 seconds\n * clock.stop("+10");\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n this.log("stop", computedTime);\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this._tickSource.stop(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("stop", computedTime);\n }\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n this._tickSource.pause(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("pause", computedTime);\n }\n }\n return this;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked.\n */\n get ticks() {\n return Math.ceil(this.getTicksAtTime(this.now()));\n }\n set ticks(t) {\n this._tickSource.ticks = t;\n }\n /**\n * The time since ticks=0 that the Clock has been running. Accounts for tempo curves\n */\n get seconds() {\n return this._tickSource.seconds;\n }\n set seconds(s) {\n this._tickSource.seconds = s;\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._tickSource.getSecondsAtTime(time);\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n this._tickSource.setTicksAtTime(ticks, time);\n return this;\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n return this._tickSource.getTimeOfTick(tick, before);\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return this._tickSource.getTicksAtTime(time);\n }\n /**\n * Get the time of the next tick\n * @param offset The tick number.\n */\n nextTickTime(offset, when) {\n const computedTime = this.toSeconds(when);\n const currentTick = this.getTicksAtTime(computedTime);\n return this._tickSource.getTimeOfTick(currentTick + offset, computedTime);\n }\n /**\n * The scheduling loop.\n */\n _loop() {\n const startTime = this._lastUpdate;\n const endTime = this.now();\n this._lastUpdate = endTime;\n this.log("loop", startTime, endTime);\n if (startTime !== endTime) {\n // the state change events\n this._state.forEachBetween(startTime, endTime, e => {\n switch (e.state) {\n case "started":\n const offset = this._tickSource.getTicksAtTime(e.time);\n this.emit("start", e.time, offset);\n break;\n case "stopped":\n if (e.time !== 0) {\n this.emit("stop", e.time);\n }\n break;\n case "paused":\n this.emit("pause", e.time);\n break;\n }\n });\n // the tick callbacks\n this._tickSource.forEachTickBetween(startTime, endTime, (time, ticks) => {\n this.callback(time, ticks);\n });\n }\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n * @example\n * const clock = new Tone.Clock();\n * clock.start("+0.1");\n * clock.getStateAtTime("+0.1"); // returns "started"\n */\n getStateAtTime(time) {\n const computedTime = this.toSeconds(time);\n return this._state.getValueAtTime(computedTime);\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.context.off("tick", this._boundLoop);\n this._tickSource.dispose();\n this._state.dispose();\n return this;\n }\n}\nEmitter.mixin(Clock_Clock);\n//# sourceMappingURL=Clock.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Delay.js\n\n\n\n\n/**\n * Wrapper around Web Audio\'s native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface).\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst delay = new Tone.Delay(0.1).toDestination();\n * \t// connect the signal to both the delay and the destination\n * \tconst pulse = new Tone.PulseOscillator().connect(delay).toDestination();\n * \t// start and stop the pulse\n * \tpulse.start(0).stop(0.01);\n * }, 0.5, 1);\n */\nclass Delay_Delay extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]));\n this.name = "Delay";\n const options = optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]);\n const maxDelayInSeconds = this.toSeconds(options.maxDelay);\n this._maxDelay = Math.max(maxDelayInSeconds, this.toSeconds(options.delayTime));\n this._delayNode = this.input = this.output = this.context.createDelay(maxDelayInSeconds);\n this.delayTime = new Param({\n context: this.context,\n param: this._delayNode.delayTime,\n units: "time",\n value: options.delayTime,\n minValue: 0,\n maxValue: this.maxDelay,\n });\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0,\n maxDelay: 1,\n });\n }\n /**\n * The maximum delay time. This cannot be changed after\n * the value is passed into the constructor.\n */\n get maxDelay() {\n return this._maxDelay;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._delayNode.disconnect();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Delay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Offline.js\n\n\n\n\n/**\n * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.\n * The OfflineAudioContext is capable of rendering much faster than real time in many cases.\n * The callback function also passes in an offline instance of [[Context]] which can be used\n * to schedule events along the Transport.\n * @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.\n * @param duration the amount of time to record for.\n * @return The promise which is invoked with the ToneAudioBuffer of the recorded output.\n * @example\n * // render 2 seconds of the oscillator\n * Tone.Offline(() => {\n * \t// only nodes created in this callback will be recorded\n * \tconst oscillator = new Tone.Oscillator().toDestination().start(0);\n * }, 2).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @example\n * // can also schedule events along the Transport\n * // using the passed in Offline Transport\n * Tone.Offline(({ transport }) => {\n * \tconst osc = new Tone.Oscillator().toDestination();\n * \ttransport.schedule(time => {\n * \t\tosc.start(time).stop(time + 0.1);\n * \t}, 1);\n * \t// make sure to start the transport\n * \ttransport.start(0.2);\n * }, 4).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @category Core\n */\nfunction Offline(callback, duration, channels = 2, sampleRate = getContext().sampleRate) {\n return __awaiter(this, void 0, void 0, function* () {\n // set the OfflineAudioContext based on the current context\n const originalContext = getContext();\n const context = new OfflineContext(channels, duration, sampleRate);\n setContext(context);\n // invoke the callback/scheduling\n yield callback(context);\n // then render the audio\n const bufferPromise = context.render();\n // return the original AudioContext\n setContext(originalContext);\n // await the rendering\n const buffer = yield bufferPromise;\n // return the audio\n return new ToneAudioBuffer(buffer);\n });\n}\n//# sourceMappingURL=Offline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffers.js\n\n\n\n\n\n\n/**\n * A data structure for holding multiple buffers in a Map-like datastructure.\n *\n * @example\n * const pianoSamples = new Tone.ToneAudioBuffers({\n * \tA1: "https://tonejs.github.io/audio/casio/A1.mp3",\n * \tA2: "https://tonejs.github.io/audio/casio/A2.mp3",\n * }, () => {\n * \tconst player = new Tone.Player().toDestination();\n * \t// play one of the samples when they all load\n * \tplayer.buffer = pianoSamples.get("A2");\n * \tplayer.start();\n * });\n * @example\n * // To pass in additional parameters in the second parameter\n * const buffers = new Tone.ToneAudioBuffers({\n * \t urls: {\n * \t\t A1: "A1.mp3",\n * \t\t A2: "A2.mp3",\n * \t },\n * \t onload: () => console.log("loaded"),\n * \t baseUrl: "https://tonejs.github.io/audio/casio/"\n * });\n * @category Core\n */\nclass ToneAudioBuffers_ToneAudioBuffers extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffers";\n /**\n * All of the buffers\n */\n this._buffers = new Map();\n /**\n * Keep track of the number of loaded buffers\n */\n this._loadingCount = 0;\n const options = Defaults_optionsFromArguments(ToneAudioBuffers_ToneAudioBuffers.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n this.baseUrl = options.baseUrl;\n // add each one\n Object.keys(options.urls).forEach(name => {\n this._loadingCount++;\n const url = options.urls[name];\n this.add(name, url, this._bufferLoaded.bind(this, options.onload), options.onerror);\n });\n }\n static getDefaults() {\n return {\n baseUrl: "",\n onerror: Interface_noOp,\n onload: Interface_noOp,\n urls: {},\n };\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name.toString());\n }\n /**\n * Get a buffer by name. If an array was loaded,\n * then use the array index.\n * @param name The key or index of the buffer.\n */\n get(name) {\n Debug_assert(this.has(name), `ToneAudioBuffers has no buffer named: ${name}`);\n return this._buffers.get(name.toString());\n }\n /**\n * A buffer was loaded. decrement the counter.\n */\n _bufferLoaded(callback) {\n this._loadingCount--;\n if (this._loadingCount === 0 && callback) {\n callback();\n }\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return Array.from(this._buffers).every(([_, buffer]) => buffer.loaded);\n }\n /**\n * Add a buffer by name and url to the Buffers\n * @param name A unique name to give the buffer\n * @param url Either the url of the bufer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n * @param onerror Invoked if the buffer can\'t be loaded\n */\n add(name, url, callback = Interface_noOp, onerror = Interface_noOp) {\n if (TypeCheck_isString(url)) {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(this.baseUrl + url, callback, onerror));\n }\n else {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(url, callback, onerror));\n }\n return this;\n }\n dispose() {\n super.dispose();\n this._buffers.forEach(buffer => buffer.dispose());\n this._buffers.clear();\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioBuffers.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Midi.js\n\n\n\n/**\n * Midi is a primitive type for encoding Time values.\n * Midi can be constructed with or without the `new` keyword. Midi can be passed\n * into the parameter of any method which takes time as an argument.\n * @category Unit\n */\nclass Midi_MidiClass extends (/* unused pure expression or super */ null && (FrequencyClass)) {\n constructor() {\n super(...arguments);\n this.name = "MidiClass";\n this.defaultUnits = "midi";\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return ftom(super._frequencyToUnits(freq));\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ftom(super._ticksToUnits(ticks));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return ftom(super._beatsToUnits(beats));\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return ftom(super._secondsToUnits(seconds));\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toMidi(); // 60\n */\n toMidi() {\n return this.valueOf();\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toFrequency(); // 261.6255653005986\n */\n toFrequency() {\n return mtof(this.toMidi());\n }\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed MidiClass\n * @example\n * Tone.Midi("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Midi_MidiClass(this.context, this.toMidi() + interval);\n }\n}\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n */\nfunction Midi(value, units) {\n return new Midi_MidiClass(getContext(), value, units);\n}\n//# sourceMappingURL=Midi.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Ticks.js\n\n\n/**\n * Ticks is a primitive type for encoding Time values.\n * Ticks can be constructed with or without the `new` keyword. Ticks can be passed\n * into the parameter of any method which takes time as an argument.\n * @example\n * const t = Tone.Ticks("4n"); // a quarter note as ticks\n * @category Unit\n */\nclass Ticks_TicksClass extends TransportTime_TransportTimeClass {\n constructor() {\n super(...arguments);\n this.name = "Ticks";\n this.defaultUnits = "i";\n }\n /**\n * Get the current time in the given units\n */\n _now() {\n return this.context.transport.ticks;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return this._getPPQ() * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return Math.floor(seconds / (60 / this._getBpm()) * this._getPPQ());\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ticks;\n }\n /**\n * Return the time in ticks\n */\n toTicks() {\n return this.valueOf();\n }\n /**\n * Return the time in seconds\n */\n toSeconds() {\n return (this.valueOf() / this._getPPQ()) * (60 / this._getBpm());\n }\n}\n/**\n * Convert a time representation to ticks\n * @category Unit\n */\nfunction Ticks(value, units) {\n return new Ticks_TicksClass(getContext(), value, units);\n}\n//# sourceMappingURL=Ticks.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Draw.js\n\n\n\n/**\n * Draw is useful for synchronizing visuals and audio events.\n * Callbacks from Tone.Transport or any of the Tone.Event classes\n * always happen _before_ the scheduled time and are not synchronized\n * to the animation frame so they are not good for triggering tightly\n * synchronized visuals and sound. Draw makes it easy to schedule\n * callbacks using the AudioContext time and uses requestAnimationFrame.\n * @example\n * Tone.Transport.schedule((time) => {\n * \t// use the time argument to schedule a callback with Draw\n * \tTone.Draw.schedule(() => {\n * \t\t// do drawing or DOM manipulation here\n * \t\tconsole.log(time);\n * \t}, time);\n * }, "+0.5");\n * Tone.Transport.start();\n * @category Core\n */\nclass Draw extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n this.name = "Draw";\n /**\n * The duration after which events are not invoked.\n */\n this.expiration = 0.25;\n /**\n * The amount of time before the scheduled time\n * that the callback can be invoked. Default is\n * half the time of an animation frame (0.008 seconds).\n */\n this.anticipation = 0.008;\n /**\n * All of the events.\n */\n this._events = new Timeline();\n /**\n * The draw loop\n */\n this._boundDrawLoop = this._drawLoop.bind(this);\n /**\n * The animation frame id\n */\n this._animationFrame = -1;\n }\n /**\n * Schedule a function at the given time to be invoked\n * on the nearest animation frame.\n * @param callback Callback is invoked at the given time.\n * @param time The time relative to the AudioContext time to invoke the callback.\n * @example\n * Tone.Transport.scheduleRepeat(time => {\n * \tTone.Draw.schedule(() => console.log(time), time);\n * }, 1);\n * Tone.Transport.start();\n */\n schedule(callback, time) {\n this._events.add({\n callback,\n time: this.toSeconds(time),\n });\n // start the draw loop on the first event\n if (this._events.length === 1) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n return this;\n }\n /**\n * Cancel events scheduled after the given time\n * @param after Time after which scheduled events will be removed from the scheduling timeline.\n */\n cancel(after) {\n this._events.cancel(this.toSeconds(after));\n return this;\n }\n /**\n * The draw loop\n */\n _drawLoop() {\n const now = this.context.currentTime;\n while (this._events.length && this._events.peek().time - this.anticipation <= now) {\n const event = this._events.shift();\n if (event && now - event.time <= this.expiration) {\n event.callback();\n }\n }\n if (this._events.length > 0) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n cancelAnimationFrame(this._animationFrame);\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.draw = new Draw({ context });\n});\nonContextClose(context => {\n context.draw.dispose();\n});\n//# sourceMappingURL=Draw.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/IntervalTimeline.js\n\n\n\n/**\n * Similar to Tone.Timeline, but all events represent\n * intervals with both "time" and "duration" times. The\n * events are placed in a tree structure optimized\n * for querying an intersection point with the timeline\n * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)\n * to represent the data.\n */\nclass IntervalTimeline extends Tone {\n constructor() {\n super(...arguments);\n this.name = "IntervalTimeline";\n /**\n * The root node of the inteval tree\n */\n this._root = null;\n /**\n * Keep track of the length of the timeline.\n */\n this._length = 0;\n }\n /**\n * The event to add to the timeline. All events must\n * have a time and duration value\n * @param event The event to add to the timeline\n */\n add(event) {\n Debug_assert(TypeCheck_isDefined(event.time), "Events must have a time property");\n Debug_assert(TypeCheck_isDefined(event.duration), "Events must have a duration parameter");\n event.time = event.time.valueOf();\n let node = new IntervalNode(event.time, event.time + event.duration, event);\n if (this._root === null) {\n this._root = node;\n }\n else {\n this._root.insert(node);\n }\n this._length++;\n // Restructure tree to be balanced\n while (node !== null) {\n node.updateHeight();\n node.updateMax();\n this._rebalance(node);\n node = node.parent;\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param event The event to remove from the timeline\n */\n remove(event) {\n if (this._root !== null) {\n const results = [];\n this._root.search(event.time, results);\n for (const node of results) {\n if (node.event === event) {\n this._removeNode(node);\n this._length--;\n break;\n }\n }\n }\n return this;\n }\n /**\n * The number of items in the timeline.\n * @readOnly\n */\n get length() {\n return this._length;\n }\n /**\n * Remove events whose time time is after the given time\n * @param after The time to query.\n */\n cancel(after) {\n this.forEachFrom(after, event => this.remove(event));\n return this;\n }\n /**\n * Set the root node as the given node\n */\n _setRoot(node) {\n this._root = node;\n if (this._root !== null) {\n this._root.parent = null;\n }\n }\n /**\n * Replace the references to the node in the node\'s parent\n * with the replacement node.\n */\n _replaceNodeInParent(node, replacement) {\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n this._rebalance(node.parent);\n }\n else {\n this._setRoot(replacement);\n }\n }\n /**\n * Remove the node from the tree and replace it with\n * a successor which follows the schema.\n */\n _removeNode(node) {\n if (node.left === null && node.right === null) {\n this._replaceNodeInParent(node, null);\n }\n else if (node.right === null) {\n this._replaceNodeInParent(node, node.left);\n }\n else if (node.left === null) {\n this._replaceNodeInParent(node, node.right);\n }\n else {\n const balance = node.getBalance();\n let replacement;\n let temp = null;\n if (balance > 0) {\n if (node.left.right === null) {\n replacement = node.left;\n replacement.right = node.right;\n temp = replacement;\n }\n else {\n replacement = node.left.right;\n while (replacement.right !== null) {\n replacement = replacement.right;\n }\n if (replacement.parent) {\n replacement.parent.right = replacement.left;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n }\n else if (node.right.left === null) {\n replacement = node.right;\n replacement.left = node.left;\n temp = replacement;\n }\n else {\n replacement = node.right.left;\n while (replacement.left !== null) {\n replacement = replacement.left;\n }\n if (replacement.parent) {\n replacement.parent.left = replacement.right;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n }\n else {\n this._setRoot(replacement);\n }\n if (temp) {\n this._rebalance(temp);\n }\n }\n node.dispose();\n }\n /**\n * Rotate the tree to the left\n */\n _rotateLeft(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.right the new root of this sub tree (instead of node)\n const pivotNode = node.right;\n if (pivotNode) {\n node.right = pivotNode.left;\n pivotNode.left = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Rotate the tree to the right\n */\n _rotateRight(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.left the new root of this sub tree (instead of node)\n const pivotNode = node.left;\n if (pivotNode) {\n node.left = pivotNode.right;\n pivotNode.right = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Balance the BST\n */\n _rebalance(node) {\n const balance = node.getBalance();\n if (balance > 1 && node.left) {\n if (node.left.getBalance() < 0) {\n this._rotateLeft(node.left);\n }\n else {\n this._rotateRight(node);\n }\n }\n else if (balance < -1 && node.right) {\n if (node.right.getBalance() > 0) {\n this._rotateRight(node.right);\n }\n else {\n this._rotateLeft(node);\n }\n }\n }\n /**\n * Get an event whose time and duration span the give time. Will\n * return the match whose "time" value is closest to the given time.\n * @return The event which spans the desired time\n */\n get(time) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n if (results.length > 0) {\n let max = results[0];\n for (let i = 1; i < results.length; i++) {\n if (results[i].low > max.low) {\n max = results[i];\n }\n }\n return max.event;\n }\n }\n return null;\n }\n /**\n * Iterate over everything in the timeline.\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n if (this._root !== null) {\n const allNodes = [];\n this._root.traverse(node => allNodes.push(node));\n allNodes.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the given time\n * overlaps with the time and duration time of the event.\n * @param time The time to check if items are overlapping\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the time is greater\n * than or equal to the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.searchAfter(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n if (this._root !== null) {\n this._root.traverse(node => node.dispose());\n }\n this._root = null;\n return this;\n }\n}\n//-------------------------------------\n// \tINTERVAL NODE HELPER\n//-------------------------------------\n/**\n * Represents a node in the binary search tree, with the addition\n * of a "high" value which keeps track of the highest value of\n * its children.\n * References:\n * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/\n * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf\n * @param low\n * @param high\n */\nclass IntervalNode {\n constructor(low, high, event) {\n // the nodes to the left\n this._left = null;\n // the nodes to the right\n this._right = null;\n // the parent node\n this.parent = null;\n // the number of child nodes\n this.height = 0;\n this.event = event;\n // the low value\n this.low = low;\n // the high value\n this.high = high;\n // the high value for this and all child nodes\n this.max = this.high;\n }\n /**\n * Insert a node into the correct spot in the tree\n */\n insert(node) {\n if (node.low <= this.low) {\n if (this.left === null) {\n this.left = node;\n }\n else {\n this.left.insert(node);\n }\n }\n else if (this.right === null) {\n this.right = node;\n }\n else {\n this.right.insert(node);\n }\n }\n /**\n * Search the tree for nodes which overlap\n * with the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n search(point, results) {\n // If p is to the right of the rightmost point of any interval\n // in this node and all children, there won\'t be any matches.\n if (point > this.max) {\n return;\n }\n // Search left children\n if (this.left !== null) {\n this.left.search(point, results);\n }\n // Check this node\n if (this.low <= point && this.high > point) {\n results.push(this);\n }\n // If p is to the left of the time of this interval,\n // then it can\'t be in any child to the right.\n if (this.low > point) {\n return;\n }\n // Search right children\n if (this.right !== null) {\n this.right.search(point, results);\n }\n }\n /**\n * Search the tree for nodes which are less\n * than the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n searchAfter(point, results) {\n // Check this node\n if (this.low >= point) {\n results.push(this);\n if (this.left !== null) {\n this.left.searchAfter(point, results);\n }\n }\n // search the right side\n if (this.right !== null) {\n this.right.searchAfter(point, results);\n }\n }\n /**\n * Invoke the callback on this element and both it\'s branches\n * @param {Function} callback\n */\n traverse(callback) {\n callback(this);\n if (this.left !== null) {\n this.left.traverse(callback);\n }\n if (this.right !== null) {\n this.right.traverse(callback);\n }\n }\n /**\n * Update the height of the node\n */\n updateHeight() {\n if (this.left !== null && this.right !== null) {\n this.height = Math.max(this.left.height, this.right.height) + 1;\n }\n else if (this.right !== null) {\n this.height = this.right.height + 1;\n }\n else if (this.left !== null) {\n this.height = this.left.height + 1;\n }\n else {\n this.height = 0;\n }\n }\n /**\n * Update the height of the node\n */\n updateMax() {\n this.max = this.high;\n if (this.left !== null) {\n this.max = Math.max(this.max, this.left.max);\n }\n if (this.right !== null) {\n this.max = Math.max(this.max, this.right.max);\n }\n }\n /**\n * The balance is how the leafs are distributed on the node\n * @return Negative numbers are balanced to the right\n */\n getBalance() {\n let balance = 0;\n if (this.left !== null && this.right !== null) {\n balance = this.left.height - this.right.height;\n }\n else if (this.left !== null) {\n balance = this.left.height + 1;\n }\n else if (this.right !== null) {\n balance = -(this.right.height + 1);\n }\n return balance;\n }\n /**\n * @returns true if this node is the left child of its parent\n */\n isLeftChild() {\n return this.parent !== null && this.parent.left === this;\n }\n /**\n * get/set the left node\n */\n get left() {\n return this._left;\n }\n set left(node) {\n this._left = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * get/set the right node\n */\n get right() {\n return this._right;\n }\n set right(node) {\n this._right = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * null out references.\n */\n dispose() {\n this.parent = null;\n this._left = null;\n this._right = null;\n this.event = null;\n }\n}\n//# sourceMappingURL=IntervalTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/index.js\n\n// export * from "./clock/Transport";\n\n\n\n// export * from "./context/Destination";\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// get the units and export them under the "Unit" namespace\n\n\n// export the debug stuff as Debug\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Volume.js\n\n\n\n\n/**\n * Volume is a simple volume node, useful for creating a volume fader.\n *\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * @category Component\n */\nclass Volume_Volume extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]));\n this.name = "Volume";\n const options = Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n gain: options.volume,\n units: "decibels",\n });\n this.volume = this.output.gain;\n Interface_readOnly(this, "volume");\n this._unmutedVolume = options.volume;\n // set the mute initially\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * // mute the output\n * vol.mute = true;\n */\n get mute() {\n return this.volume.value === -Infinity;\n }\n set mute(mute) {\n if (!this.mute && mute) {\n this._unmutedVolume = this.volume.value;\n // maybe it should ramp here?\n this.volume.value = -Infinity;\n }\n else if (this.mute && !mute) {\n this.volume.value = this._unmutedVolume;\n }\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.input.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Volume.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Destination.js\n\n\n\n\n\n/**\n * A single master output which is connected to the\n * AudioDestinationNode (aka your speakers).\n * It provides useful conveniences such as the ability\n * to set the volume and mute the entire application.\n * It also gives you the ability to apply master effects to your application.\n *\n * @example\n * const oscillator = new Tone.Oscillator().start();\n * // the audio will go from the oscillator to the speakers\n * oscillator.connect(Tone.getDestination());\n * // a convenience for connecting to the master output is also provided:\n * oscillator.toDestination();\n * @category Core\n */\nclass Destination extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Destination.getDefaults(), arguments));\n this.name = "Destination";\n this.input = new Volume_Volume({ context: this.context });\n this.output = new Gain_Gain({ context: this.context });\n /**\n * The volume of the master output in decibels. -Infinity is silent, and 0 is no change.\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * osc.start();\n * // ramp the volume down to silent over 10 seconds\n * Tone.getDestination().volume.rampTo(-Infinity, 10);\n */\n this.volume = this.input.volume;\n const options = Defaults_optionsFromArguments(Destination.getDefaults(), arguments);\n ToneAudioNode_connectSeries(this.input, this.output, this.context.rawContext.destination);\n this.mute = options.mute;\n this._internalChannels = [this.input, this.context.rawContext.destination, this.output];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const oscillator = new Tone.Oscillator().start().toDestination();\n * setTimeout(() => {\n * \t// mute the output\n * \tTone.Destination.mute = true;\n * }, 1000);\n */\n get mute() {\n return this.input.mute;\n }\n set mute(mute) {\n this.input.mute = mute;\n }\n /**\n * Add a master effects chain. NOTE: this will disconnect any nodes which were previously\n * chained in the master effects chain.\n * @param args All arguments will be connected in a row and the Master will be routed through it.\n * @example\n * // route all audio through a filter and compressor\n * const lowpass = new Tone.Filter(800, "lowpass");\n * const compressor = new Tone.Compressor(-18);\n * Tone.Destination.chain(lowpass, compressor);\n */\n chain(...args) {\n this.input.disconnect();\n args.unshift(this.input);\n args.push(this.output);\n ToneAudioNode_connectSeries(...args);\n return this;\n }\n /**\n * The maximum number of channels the system can output\n * @example\n * console.log(Tone.Destination.maxChannelCount);\n */\n get maxChannelCount() {\n return this.context.rawContext.destination.maxChannelCount;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.destination = new Destination({ context });\n});\nonContextClose(context => {\n context.destination.dispose();\n});\n//# sourceMappingURL=Destination.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TimelineValue.js\n\n\n/**\n * Represents a single value which is gettable and settable in a timed way\n */\nclass TimelineValue extends Tone {\n /**\n * @param initialValue The value to return if there is no scheduled values\n */\n constructor(initialValue) {\n super();\n this.name = "TimelineValue";\n /**\n * The timeline which stores the values\n */\n this._timeline = new Timeline({ memory: 10 });\n this._initialValue = initialValue;\n }\n /**\n * Set the value at the given time\n */\n set(value, time) {\n this._timeline.add({\n value, time\n });\n return this;\n }\n /**\n * Get the value at the given time\n */\n get(time) {\n const event = this._timeline.get(time);\n if (event) {\n return event.value;\n }\n else {\n return this._initialValue;\n }\n }\n}\n//# sourceMappingURL=TimelineValue.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportEvent.js\n\n/**\n * TransportEvent is an internal class used by [[Transport]]\n * to schedule events. Do no invoke this class directly, it is\n * handled from within Tone.Transport.\n */\nclass TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n /**\n * The unique id of the event\n */\n this.id = TransportEvent._eventId++;\n const options = Object.assign(TransportEvent.getDefaults(), opts);\n this.transport = transport;\n this.callback = options.callback;\n this._once = options.once;\n this.time = options.time;\n }\n static getDefaults() {\n return {\n callback: Interface_noOp,\n once: false,\n time: 0,\n };\n }\n /**\n * Invoke the event callback.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n if (this.callback) {\n this.callback(time);\n if (this._once) {\n this.transport.clear(this.id);\n }\n }\n }\n /**\n * Clean up\n */\n dispose() {\n this.callback = undefined;\n return this;\n }\n}\n/**\n * Current ID counter\n */\nTransportEvent._eventId = 0;\n//# sourceMappingURL=TransportEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportRepeatEvent.js\n\n\n/**\n * TransportRepeatEvent is an internal class used by Tone.Transport\n * to schedule repeat events. This class should not be instantiated directly.\n */\nclass TransportRepeatEvent extends TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n super(transport, opts);\n /**\n * The ID of the current timeline event\n */\n this._currentId = -1;\n /**\n * The ID of the next timeline event\n */\n this._nextId = -1;\n /**\n * The time of the next event\n */\n this._nextTick = this.time;\n /**\n * a reference to the bound start method\n */\n this._boundRestart = this._restart.bind(this);\n const options = Object.assign(TransportRepeatEvent.getDefaults(), opts);\n this.duration = new Ticks_TicksClass(transport.context, options.duration).valueOf();\n this._interval = new Ticks_TicksClass(transport.context, options.interval).valueOf();\n this._nextTick = options.time;\n this.transport.on("start", this._boundRestart);\n this.transport.on("loopStart", this._boundRestart);\n this.context = this.transport.context;\n this._restart();\n }\n static getDefaults() {\n return Object.assign({}, TransportEvent.getDefaults(), {\n duration: Infinity,\n interval: 1,\n once: false,\n });\n }\n /**\n * Invoke the callback. Returns the tick time which\n * the next event should be scheduled at.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n // create more events if necessary\n this._createEvents(time);\n // call the super class\n super.invoke(time);\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _createEvents(time) {\n // schedule the next event\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) {\n this._nextTick += this._interval;\n this._currentId = this._nextId;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _restart(time) {\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this._nextTick = this.time;\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks > this.time) {\n this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval;\n }\n this._currentId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n this._nextTick += this._interval;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this.transport.off("start", this._boundRestart);\n this.transport.off("loopStart", this._boundRestart);\n return this;\n }\n}\n//# sourceMappingURL=TransportRepeatEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Transport.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Transport for timing musical events.\n * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame)\n * Transport timing events pass in the exact time of the scheduled event\n * in the argument of the callback function. Pass that time value to the object\n * you\'re scheduling. <br><br>\n * A single transport is created for you when the library is initialized.\n * <br><br>\n * The transport emits the events: "start", "stop", "pause", and "loop" which are\n * called with the time of that event as the argument.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // repeated event every 8th note\n * Tone.Transport.scheduleRepeat((time) => {\n * \t// use the callback time to schedule events\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n");\n * // transport must be started before it starts invoking events\n * Tone.Transport.start();\n * @category Core\n */\nclass Transport extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Transport.getDefaults(), arguments));\n this.name = "Transport";\n //-------------------------------------\n // \tLOOPING\n //-------------------------------------\n /**\n * If the transport loops or not.\n */\n this._loop = new TimelineValue(false);\n /**\n * The loop start position in ticks\n */\n this._loopStart = 0;\n /**\n * The loop end position in ticks\n */\n this._loopEnd = 0;\n //-------------------------------------\n // \tTIMELINE EVENTS\n //-------------------------------------\n /**\n * All the events in an object to keep track by ID\n */\n this._scheduledEvents = {};\n /**\n * The scheduled events.\n */\n this._timeline = new Timeline();\n /**\n * Repeated events\n */\n this._repeatedEvents = new IntervalTimeline();\n /**\n * All of the synced Signals\n */\n this._syncedSignals = [];\n /**\n * The swing amount\n */\n this._swingAmount = 0;\n const options = Defaults_optionsFromArguments(Transport.getDefaults(), arguments);\n // CLOCK/TEMPO\n this._ppq = options.ppq;\n this._clock = new Clock_Clock({\n callback: this._processTick.bind(this),\n context: this.context,\n frequency: 0,\n units: "bpm",\n });\n this._bindClockEvents();\n this.bpm = this._clock.frequency;\n this._clock.frequency.multiplier = options.ppq;\n this.bpm.setValueAtTime(options.bpm, 0);\n Interface_readOnly(this, "bpm");\n this._timeSignature = options.timeSignature;\n // SWING\n this._swingTicks = options.ppq / 2; // 8n\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n bpm: 120,\n loopEnd: "4m",\n loopStart: 0,\n ppq: 192,\n swing: 0,\n swingSubdivision: "8n",\n timeSignature: 4,\n });\n }\n //-------------------------------------\n // \tTICKS\n //-------------------------------------\n /**\n * called on every tick\n * @param tickTime clock relative tick time\n */\n _processTick(tickTime, ticks) {\n // do the loop test\n if (this._loop.get(tickTime)) {\n if (ticks >= this._loopEnd) {\n this.emit("loopEnd", tickTime);\n this._clock.setTicksAtTime(this._loopStart, tickTime);\n ticks = this._loopStart;\n this.emit("loopStart", tickTime, this._clock.getSecondsAtTime(tickTime));\n this.emit("loop", tickTime);\n }\n }\n // handle swing\n if (this._swingAmount > 0 &&\n ticks % this._ppq !== 0 && // not on a downbeat\n ticks % (this._swingTicks * 2) !== 0) {\n // add some swing\n const progress = (ticks % (this._swingTicks * 2)) / (this._swingTicks * 2);\n const amount = Math.sin((progress) * Math.PI) * this._swingAmount;\n tickTime += new Ticks_TicksClass(this.context, this._swingTicks * 2 / 3).toSeconds() * amount;\n }\n // invoke the timeline events scheduled on this tick\n this._timeline.forEachAtTime(ticks, event => event.invoke(tickTime));\n }\n //-------------------------------------\n // \tSCHEDULABLE EVENTS\n //-------------------------------------\n /**\n * Schedule an event along the timeline.\n * @param callback The callback to be invoked at the time.\n * @param time The time to invoke the callback at.\n * @return The id of the event which can be used for canceling the event.\n * @example\n * // schedule an event on the 16th measure\n * Tone.Transport.schedule((time) => {\n * \t// invoked on measure 16\n * \tconsole.log("measure 16!");\n * }, "16:0:0");\n */\n schedule(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Schedule a repeated event along the timeline. The event will fire\n * at the `interval` starting at the `startTime` and for the specified\n * `duration`.\n * @param callback The callback to invoke.\n * @param interval The duration between successive callbacks. Must be a positive number.\n * @param startTime When along the timeline the events should start being invoked.\n * @param duration How long the event should repeat.\n * @return The ID of the scheduled event. Use this to cancel the event.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a callback invoked every eighth note after the first measure\n * Tone.Transport.scheduleRepeat((time) => {\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n", "1m");\n */\n scheduleRepeat(callback, interval, startTime, duration = Infinity) {\n const event = new TransportRepeatEvent(this, {\n callback,\n duration: new TimeClass(this.context, duration).toTicks(),\n interval: new TimeClass(this.context, interval).toTicks(),\n time: new TransportTime_TransportTimeClass(this.context, startTime).toTicks(),\n });\n // kick it off if the Transport is started\n // @ts-ignore\n return this._addEvent(event, this._repeatedEvents);\n }\n /**\n * Schedule an event that will be removed after it is invoked.\n * @param callback The callback to invoke once.\n * @param time The time the callback should be invoked.\n * @returns The ID of the scheduled event.\n */\n scheduleOnce(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n once: true,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Clear the passed in event id from the timeline\n * @param eventId The id of the event.\n */\n clear(eventId) {\n if (this._scheduledEvents.hasOwnProperty(eventId)) {\n const item = this._scheduledEvents[eventId.toString()];\n item.timeline.remove(item.event);\n item.event.dispose();\n delete this._scheduledEvents[eventId.toString()];\n }\n return this;\n }\n /**\n * Add an event to the correct timeline. Keep track of the\n * timeline it was added to.\n * @returns the event id which was just added\n */\n _addEvent(event, timeline) {\n this._scheduledEvents[event.id.toString()] = {\n event,\n timeline,\n };\n timeline.add(event);\n return event.id;\n }\n /**\n * Remove scheduled events from the timeline after\n * the given time. Repeated events will be removed\n * if their startTime is after the given time\n * @param after Clear all events after this time.\n */\n cancel(after = 0) {\n const computedAfter = this.toTicks(after);\n this._timeline.forEachFrom(computedAfter, event => this.clear(event.id));\n this._repeatedEvents.forEachFrom(computedAfter, event => this.clear(event.id));\n return this;\n }\n //-------------------------------------\n // \tSTART/STOP/PAUSE\n //-------------------------------------\n /**\n * Bind start/stop/pause events from the clock and emit them.\n */\n _bindClockEvents() {\n this._clock.on("start", (time, offset) => {\n offset = new Ticks_TicksClass(this.context, offset).toSeconds();\n this.emit("start", time, offset);\n });\n this._clock.on("stop", (time) => {\n this.emit("stop", time);\n });\n this._clock.on("pause", (time) => {\n this.emit("pause", time);\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped", or "paused"\n */\n get state() {\n return this._clock.getStateAtTime(this.now());\n }\n /**\n * Start the transport and all sources synced to the transport.\n * @param time The time when the transport should start.\n * @param offset The timeline offset to start the transport.\n * @example\n * // start the transport in one second starting at beginning of the 5th measure.\n * Tone.Transport.start("+1", "4:0:0");\n */\n start(time, offset) {\n let offsetTicks;\n if (TypeCheck_isDefined(offset)) {\n offsetTicks = this.toTicks(offset);\n }\n // start the clock\n this._clock.start(time, offsetTicks);\n return this;\n }\n /**\n * Stop the transport and all sources synced to the transport.\n * @param time The time when the transport should stop.\n * @example\n * Tone.Transport.stop();\n */\n stop(time) {\n this._clock.stop(time);\n return this;\n }\n /**\n * Pause the transport and all sources synced to the transport.\n */\n pause(time) {\n this._clock.pause(time);\n return this;\n }\n /**\n * Toggle the current state of the transport. If it is\n * started, it will stop it, otherwise it will start the Transport.\n * @param time The time of the event\n */\n toggle(time) {\n time = this.toSeconds(time);\n if (this._clock.getStateAtTime(time) !== "started") {\n this.start(time);\n }\n else {\n this.stop(time);\n }\n return this;\n }\n //-------------------------------------\n // \tSETTERS/GETTERS\n //-------------------------------------\n /**\n * The time signature as just the numerator over 4.\n * For example 4/4 would be just 4 and 6/8 would be 3.\n * @example\n * // common time\n * Tone.Transport.timeSignature = 4;\n * // 7/8\n * Tone.Transport.timeSignature = [7, 8];\n * // this will be reduced to a single number\n * Tone.Transport.timeSignature; // returns 3.5\n */\n get timeSignature() {\n return this._timeSignature;\n }\n set timeSignature(timeSig) {\n if (TypeCheck_isArray(timeSig)) {\n timeSig = (timeSig[0] / timeSig[1]) * 4;\n }\n this._timeSignature = timeSig;\n }\n /**\n * When the Transport.loop = true, this is the starting position of the loop.\n */\n get loopStart() {\n return new TimeClass(this.context, this._loopStart, "i").toSeconds();\n }\n set loopStart(startPosition) {\n this._loopStart = this.toTicks(startPosition);\n }\n /**\n * When the Transport.loop = true, this is the ending position of the loop.\n */\n get loopEnd() {\n return new TimeClass(this.context, this._loopEnd, "i").toSeconds();\n }\n set loopEnd(endPosition) {\n this._loopEnd = this.toTicks(endPosition);\n }\n /**\n * If the transport loops or not.\n */\n get loop() {\n return this._loop.get(this.now());\n }\n set loop(loop) {\n this._loop.set(loop, this.now());\n }\n /**\n * Set the loop start and stop at the same time.\n * @example\n * // loop over the first measure\n * Tone.Transport.setLoopPoints(0, "1m");\n * Tone.Transport.loop = true;\n */\n setLoopPoints(startPosition, endPosition) {\n this.loopStart = startPosition;\n this.loopEnd = endPosition;\n return this;\n }\n /**\n * The swing value. Between 0-1 where 1 equal to the note + half the subdivision.\n */\n get swing() {\n return this._swingAmount;\n }\n set swing(amount) {\n // scale the values to a normal range\n this._swingAmount = amount;\n }\n /**\n * Set the subdivision which the swing will be applied to.\n * The default value is an 8th note. Value must be less\n * than a quarter note.\n */\n get swingSubdivision() {\n return new Ticks_TicksClass(this.context, this._swingTicks).toNotation();\n }\n set swingSubdivision(subdivision) {\n this._swingTicks = this.toTicks(subdivision);\n }\n /**\n * The Transport\'s position in Bars:Beats:Sixteenths.\n * Setting the value will jump to that position right away.\n */\n get position() {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return new Ticks_TicksClass(this.context, ticks).toBarsBeatsSixteenths();\n }\n set position(progress) {\n const ticks = this.toTicks(progress);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s position in seconds\n * Setting the value will jump to that position right away.\n */\n get seconds() {\n return this._clock.seconds;\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this._clock.frequency.timeToTicks(s, now);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s loop position as a normalized value. Always\n * returns 0 if the transport if loop is not true.\n */\n get progress() {\n if (this.loop) {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return (ticks - this._loopStart) / (this._loopEnd - this._loopStart);\n }\n else {\n return 0;\n }\n }\n /**\n * The transports current tick position.\n */\n get ticks() {\n return this._clock.ticks;\n }\n set ticks(t) {\n if (this._clock.ticks !== t) {\n const now = this.now();\n // stop everything synced to the transport\n if (this.state === "started") {\n const ticks = this._clock.getTicksAtTime(now);\n // schedule to start on the next tick, #573\n const remainingTick = this._clock.frequency.getDurationOfTicks(Math.ceil(ticks) - ticks, now);\n const time = now + remainingTick;\n this.emit("stop", time);\n this._clock.setTicksAtTime(t, time);\n // restart it with the new time\n this.emit("start", time, this._clock.getSecondsAtTime(time));\n }\n else {\n this._clock.setTicksAtTime(t, now);\n }\n }\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return Math.round(this._clock.getTicksAtTime(time));\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._clock.getSecondsAtTime(time);\n }\n /**\n * Pulses Per Quarter note. This is the smallest resolution\n * the Transport timing supports. This should be set once\n * on initialization and not set again. Changing this value\n * after other objects have been created can cause problems.\n */\n get PPQ() {\n return this._clock.frequency.multiplier;\n }\n set PPQ(ppq) {\n this._clock.frequency.multiplier = ppq;\n }\n //-------------------------------------\n // \tSYNCING\n //-------------------------------------\n /**\n * Returns the time aligned to the next subdivision\n * of the Transport. If the Transport is not started,\n * it will return 0.\n * Note: this will not work precisely during tempo ramps.\n * @param subdivision The subdivision to quantize to\n * @return The context time of the next subdivision.\n * @example\n * // the transport must be started, otherwise returns 0\n * Tone.Transport.start();\n * Tone.Transport.nextSubdivision("4n");\n */\n nextSubdivision(subdivision) {\n subdivision = this.toTicks(subdivision);\n if (this.state !== "started") {\n // if the transport\'s not started, return 0\n return 0;\n }\n else {\n const now = this.now();\n // the remainder of the current ticks and the subdivision\n const transportPos = this.getTicksAtTime(now);\n const remainingTicks = subdivision - transportPos % subdivision;\n return this._clock.nextTickTime(remainingTicks, now);\n }\n }\n /**\n * Attaches the signal to the tempo control signal so that\n * any changes in the tempo will change the signal in the same\n * ratio.\n *\n * @param signal\n * @param ratio Optionally pass in the ratio between the two signals.\n * \t\t\tOtherwise it will be computed based on their current values.\n */\n syncSignal(signal, ratio) {\n if (!ratio) {\n // get the sync ratio\n const now = this.now();\n if (signal.getValueAtTime(now) !== 0) {\n const bpm = this.bpm.getValueAtTime(now);\n const computedFreq = 1 / (60 / bpm / this.PPQ);\n ratio = signal.getValueAtTime(now) / computedFreq;\n }\n else {\n ratio = 0;\n }\n }\n const ratioSignal = new Gain_Gain(ratio);\n // @ts-ignore\n this.bpm.connect(ratioSignal);\n // @ts-ignore\n ratioSignal.connect(signal._param);\n this._syncedSignals.push({\n initial: signal.value,\n ratio: ratioSignal,\n signal,\n });\n signal.value = 0;\n return this;\n }\n /**\n * Unsyncs a previously synced signal from the transport\'s control.\n * See Transport.syncSignal.\n */\n unsyncSignal(signal) {\n for (let i = this._syncedSignals.length - 1; i >= 0; i--) {\n const syncedSignal = this._syncedSignals[i];\n if (syncedSignal.signal === signal) {\n syncedSignal.ratio.dispose();\n syncedSignal.signal.value = syncedSignal.initial;\n this._syncedSignals.splice(i, 1);\n }\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._clock.dispose();\n Interface_writable(this, "bpm");\n this._timeline.dispose();\n this._repeatedEvents.dispose();\n return this;\n }\n}\nEmitter.mixin(Transport);\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.transport = new Transport({ context });\n});\nonContextClose(context => {\n context.transport.dispose();\n});\n//# sourceMappingURL=Transport.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Source.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for sources.\n * start/stop of this.context.transport.\n *\n * ```\n * // Multiple state change events can be chained together,\n * // but must be set in the correct order and with ascending times\n * // OK\n * state.start().stop("+0.2");\n * // OK\n * state.start().stop("+0.2").start("+0.4").stop("+0.7")\n * // BAD\n * state.stop("+0.2").start();\n * // BAD\n * state.start("+0.3").stop("+0.2");\n * ```\n */\nclass Source_Source extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * Sources have no inputs\n */\n this.input = undefined;\n /**\n * Keep track of the scheduled state.\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * The synced `start` callback function from the transport\n */\n this._synced = false;\n /**\n * Keep track of all of the scheduled event ids\n */\n this._scheduled = [];\n /**\n * Placeholder functions for syncing/unsyncing to transport\n */\n this._syncedStart = Interface_noOp;\n this._syncedStop = Interface_noOp;\n this._state.memory = 100;\n this._state.increasing = true;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n mute: options.mute,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n this.onstop = options.onstop;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n onstop: Interface_noOp,\n volume: 0,\n });\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/ahntone_c3.mp3", () => {\n * \tplayer.start();\n * \tconsole.log(player.state);\n * }).toDestination();\n */\n get state() {\n if (this._synced) {\n if (this.context.transport.state === "started") {\n return this._state.getValueAtTime(this.context.transport.seconds);\n }\n else {\n return "stopped";\n }\n }\n else {\n return this._state.getValueAtTime(this.now());\n }\n }\n /**\n * Mute the output.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // mute the output\n * osc.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * Ensure that the scheduled time is not before the current time.\n * Should only be used when scheduled unsynced.\n */\n _clampToCurrentTime(time) {\n if (this._synced) {\n return time;\n }\n else {\n return Math.max(time, this.context.currentTime);\n }\n }\n /**\n * Start the source at the specified time. If no time is given,\n * start the source now.\n * @param time When the source should be started.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start("+0.5"); // starts the source 0.5 seconds from now\n */\n start(time, offset, duration) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n // if it\'s started, stop it and restart it\n if (!this._synced && this._state.getValueAtTime(computedTime) === "started") {\n // time should be strictly greater than the previous start time\n Debug_assert(GT(computedTime, this._state.get(computedTime).time), "Start time must be strictly greater than previous start time");\n this._state.cancel(computedTime);\n this._state.setStateAtTime("started", computedTime);\n this.log("restart", computedTime);\n this.restart(computedTime, offset, duration);\n }\n else {\n this.log("start", computedTime);\n this._state.setStateAtTime("started", computedTime);\n if (this._synced) {\n // add the offset time to the event\n const event = this._state.get(computedTime);\n if (event) {\n event.offset = this.toSeconds(Defaults_defaultArg(offset, 0));\n event.duration = duration ? this.toSeconds(duration) : undefined;\n }\n const sched = this.context.transport.schedule(t => {\n this._start(t, offset, duration);\n }, computedTime);\n this._scheduled.push(sched);\n // if the transport is already started\n // and the time is greater than where the transport is\n if (this.context.transport.state === "started" &&\n this.context.transport.getSecondsAtTime(this.immediate()) > computedTime) {\n this._syncedStart(this.now(), this.context.transport.seconds);\n }\n }\n else {\n assertContextRunning(this.context);\n this._start(computedTime, offset, duration);\n }\n }\n return this;\n }\n /**\n * Stop the source at the specified time. If no time is given,\n * stop the source now.\n * @param time When the source should be stopped.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start();\n * source.stop("+0.5"); // stops the source 0.5 seconds from now\n */\n stop(time) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n if (this._state.getValueAtTime(computedTime) === "started" || TypeCheck_isDefined(this._state.getNextState("started", computedTime))) {\n this.log("stop", computedTime);\n if (!this._synced) {\n this._stop(computedTime);\n }\n else {\n const sched = this.context.transport.schedule(this._stop.bind(this), computedTime);\n this._scheduled.push(sched);\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n }\n return this;\n }\n /**\n * Restart the source.\n */\n restart(time, offset, duration) {\n time = this.toSeconds(time);\n if (this._state.getValueAtTime(time) === "started") {\n this._state.cancel(time);\n this._restart(time, offset, duration);\n }\n return this;\n }\n /**\n * Sync the source to the Transport so that all subsequent\n * calls to `start` and `stop` are synced to the TransportTime\n * instead of the AudioContext time.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // sync the source so that it plays between 0 and 0.3 on the Transport\'s timeline\n * osc.sync().start(0).stop(0.3);\n * // start the transport.\n * Tone.Transport.start();\n * // set it to loop once a second\n * Tone.Transport.loop = true;\n * Tone.Transport.loopEnd = 1;\n */\n sync() {\n if (!this._synced) {\n this._synced = true;\n this._syncedStart = (time, offset) => {\n if (offset > 0) {\n // get the playback state at that time\n const stateEvent = this._state.get(offset);\n // listen for start events which may occur in the middle of the sync\'ed time\n if (stateEvent && stateEvent.state === "started" && stateEvent.time !== offset) {\n // get the offset\n const startOffset = offset - this.toSeconds(stateEvent.time);\n let duration;\n if (stateEvent.duration) {\n duration = this.toSeconds(stateEvent.duration) - startOffset;\n }\n this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration);\n }\n }\n };\n this._syncedStop = time => {\n const seconds = this.context.transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0));\n if (this._state.getValueAtTime(seconds) === "started") {\n this._stop(time);\n }\n };\n this.context.transport.on("start", this._syncedStart);\n this.context.transport.on("loopStart", this._syncedStart);\n this.context.transport.on("stop", this._syncedStop);\n this.context.transport.on("pause", this._syncedStop);\n this.context.transport.on("loopEnd", this._syncedStop);\n }\n return this;\n }\n /**\n * Unsync the source to the Transport. See Source.sync\n */\n unsync() {\n if (this._synced) {\n this.context.transport.off("stop", this._syncedStop);\n this.context.transport.off("pause", this._syncedStop);\n this.context.transport.off("loopEnd", this._syncedStop);\n this.context.transport.off("start", this._syncedStart);\n this.context.transport.off("loopStart", this._syncedStart);\n }\n this._synced = false;\n // clear all of the scheduled ids\n this._scheduled.forEach(id => this.context.transport.clear(id));\n this._scheduled = [];\n this._state.cancel(0);\n // stop it also\n this._stop(0);\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.onstop = Interface_noOp;\n this.unsync();\n this._volume.dispose();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Source.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/ToneBufferSource.js\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native BufferSourceNode.\n * @category Source\n */\nclass ToneBufferSource_ToneBufferSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]));\n this.name = "ToneBufferSource";\n /**\n * The oscillator\n */\n this._source = this.context.createBufferSource();\n this._internalChannels = [this._source];\n /**\n * indicators if the source has started/stopped\n */\n this._sourceStarted = false;\n this._sourceStopped = false;\n const options = Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this._source.onended = () => this._stopSource();\n /**\n * The playbackRate of the buffer\n */\n this.playbackRate = new Param_Param({\n context: this.context,\n param: this._source.playbackRate,\n units: "positive",\n value: options.playbackRate,\n });\n // set some values initially\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer(options.url, options.onload, options.onerror);\n this._internalChannels.push(this._source);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n url: new ToneAudioBuffer_ToneAudioBuffer(),\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n });\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(t) {\n this._fadeIn = t;\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(t) {\n this._fadeOut = t;\n }\n /**\n * The curve applied to the fades, either "linear" or "exponential"\n */\n get curve() {\n return this._curve;\n }\n set curve(t) {\n this._curve = t;\n }\n /**\n * Start the buffer\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n * @param gain The gain to play the buffer back at.\n */\n start(time, offset, duration, gain = 1) {\n Debug_assert(this.buffer.loaded, "buffer is either not set or not loaded");\n const computedTime = this.toSeconds(time);\n // apply the gain envelope\n this._startGain(computedTime, gain);\n // if it\'s a loop the default offset is the loopstart point\n if (this.loop) {\n offset = Defaults_defaultArg(offset, this.loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // make sure the offset is not less than 0\n let computedOffset = Math.max(this.toSeconds(offset), 0);\n // start the buffer source\n if (this.loop) {\n // modify the offset if it\'s greater than the loop time\n const loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n const loopStart = this.toSeconds(this.loopStart);\n const loopDuration = loopEnd - loopStart;\n // move the offset back\n if (GTE(computedOffset, loopEnd)) {\n computedOffset = ((computedOffset - loopStart) % loopDuration) + loopStart;\n }\n // when the offset is very close to the duration, set it to 0\n if (EQ(computedOffset, this.buffer.duration)) {\n computedOffset = 0;\n }\n }\n // this.buffer.loaded would have return false if the AudioBuffer was undefined\n this._source.buffer = this.buffer.get();\n this._source.loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n if (LT(computedOffset, this.buffer.duration)) {\n this._sourceStarted = true;\n this._source.start(computedTime, computedOffset);\n }\n // if a duration is given, schedule a stop\n if (TypeCheck_isDefined(duration)) {\n let computedDur = this.toSeconds(duration);\n // make sure it\'s never negative\n computedDur = Math.max(computedDur, 0);\n this.stop(computedTime + computedDur);\n }\n return this;\n }\n _stopSource(time) {\n if (!this._sourceStopped && this._sourceStarted) {\n this._sourceStopped = true;\n this._source.stop(this.toSeconds(time));\n this._onended();\n }\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._source.loopStart;\n }\n set loopStart(loopStart) {\n this._source.loopStart = this.toSeconds(loopStart);\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._source.loopEnd;\n }\n set loopEnd(loopEnd) {\n this._source.loopEnd = this.toSeconds(loopEnd);\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n */\n get loop() {\n return this._source.loop;\n }\n set loop(loop) {\n this._source.loop = loop;\n if (this._sourceStarted) {\n this.cancelStop();\n }\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._source.onended = null;\n this._source.disconnect();\n this._buffer.dispose();\n this.playbackRate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneBufferSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Noise.js\n\n\n\n\n\n/**\n * Noise is a noise generator. It uses looped noise buffers to save on performance.\n * Noise supports the noise types: "pink", "white", and "brown". Read more about\n * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise).\n *\n * @example\n * // initialize the noise and start\n * const noise = new Tone.Noise("pink").start();\n * // make an autofilter to shape the noise\n * const autoFilter = new Tone.AutoFilter({\n * \tfrequency: "8n",\n * \tbaseFrequency: 200,\n * \toctaves: 8\n * }).toDestination().start();\n * // connect the noise\n * noise.connect(autoFilter);\n * // start the autofilter LFO\n * autoFilter.start();\n * @category Source\n */\nclass Noise_Noise extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]));\n this.name = "Noise";\n /**\n * Private reference to the source\n */\n this._source = null;\n const options = optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]);\n this._playbackRate = options.playbackRate;\n this.type = options.type;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n fadeIn: 0,\n fadeOut: 0,\n playbackRate: 1,\n type: "white",\n });\n }\n /**\n * The type of the noise. Can be "white", "brown", or "pink".\n * @example\n * const noise = new Tone.Noise().toDestination().start();\n * noise.type = "brown";\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type in _noiseBuffers, "Noise: invalid type: " + type);\n if (this._type !== type) {\n this._type = type;\n // if it\'s playing, stop and restart it\n if (this.state === "started") {\n const now = this.now();\n this._stop(now);\n this._start(now);\n }\n }\n }\n /**\n * The playback rate of the noise. Affects\n * the "frequency" of the noise.\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n if (this._source) {\n this._source.playbackRate.value = rate;\n }\n }\n /**\n * internal start method\n */\n _start(time) {\n const buffer = _noiseBuffers[this._type];\n this._source = new ToneBufferSource({\n url: buffer,\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n loop: true,\n onended: () => this.onstop(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001));\n }\n /**\n * internal stop method\n */\n _stop(time) {\n if (this._source) {\n this._source.stop(this.toSeconds(time));\n this._source = null;\n }\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(time) {\n this._fadeIn = time;\n if (this._source) {\n this._source.fadeIn = this._fadeIn;\n }\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(time) {\n this._fadeOut = time;\n if (this._source) {\n this._source.fadeOut = this._fadeOut;\n }\n }\n _restart(time) {\n // TODO could be optimized by cancelling the buffer source \'stop\'\n this._stop(time);\n this._start(time);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this._source) {\n this._source.disconnect();\n }\n return this;\n }\n}\n//--------------------\n// THE NOISE BUFFERS\n//--------------------\n// Noise buffer stats\nconst BUFFER_LENGTH = 44100 * 5;\nconst NUM_CHANNELS = 2;\n/**\n * Cache the noise buffers\n */\nconst _noiseCache = {\n brown: null,\n pink: null,\n white: null,\n};\n/**\n * The noise arrays. Generated on initialization.\n * borrowed heavily from https://github.com/zacharydenton/noise.js\n * (c) 2013 Zach Denton (MIT)\n */\nconst _noiseBuffers = {\n get brown() {\n if (!_noiseCache.brown) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let lastOut = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n channel[i] = (lastOut + (0.02 * white)) / 1.02;\n lastOut = channel[i];\n channel[i] *= 3.5; // (roughly) compensate for gain\n }\n }\n _noiseCache.brown = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.brown;\n },\n get pink() {\n if (!_noiseCache.pink) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.96900 * b2 + white * 0.1538520;\n b3 = 0.86650 * b3 + white * 0.3104856;\n b4 = 0.55000 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.0168980;\n channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n channel[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n }\n _noiseCache.pink = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.pink;\n },\n get white() {\n if (!_noiseCache.white) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n channel[i] = Math.random() * 2 - 1;\n }\n }\n _noiseCache.white = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.white;\n },\n};\n//# sourceMappingURL=Noise.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/UserMedia.js\n\n\n\n\n\n\n\n/**\n * UserMedia uses MediaDevices.getUserMedia to open up and external microphone or audio input.\n * Check [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n * to see which browsers are supported. Access to an external input\n * is limited to secure (HTTPS) connections.\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia().connect(meter);\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * \tconsole.log("mic open");\n * \t// print the incoming mic levels in decibels\n * \tsetInterval(() => console.log(meter.getValue()), 100);\n * }).catch(e => {\n * \t// promise is rejected when the user doesn\'t have or allow mic access\n * \tconsole.log("mic not open");\n * });\n * @category Source\n */\nclass UserMedia extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]));\n this.name = "UserMedia";\n const options = optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]);\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0\n });\n }\n /**\n * Open the media stream. If a string is passed in, it is assumed\n * to be the label or id of the stream, if a number is passed in,\n * it is the input number of the stream.\n * @param labelOrId The label or id of the audio input media device.\n * With no argument, the default stream is opened.\n * @return The promise is resolved when the stream is open.\n */\n open(labelOrId) {\n return __awaiter(this, void 0, void 0, function* () {\n assert(UserMedia.supported, "UserMedia is not supported");\n // close the previous stream\n if (this.state === "started") {\n this.close();\n }\n const devices = yield UserMedia.enumerateDevices();\n if (isNumber(labelOrId)) {\n this._device = devices[labelOrId];\n }\n else {\n this._device = devices.find((device) => {\n return device.label === labelOrId || device.deviceId === labelOrId;\n });\n // didn\'t find a matching device\n if (!this._device && devices.length > 0) {\n this._device = devices[0];\n }\n assert(isDefined(this._device), `No matching device ${labelOrId}`);\n }\n // do getUserMedia\n const constraints = {\n audio: {\n echoCancellation: false,\n sampleRate: this.context.sampleRate,\n noiseSuppression: false,\n mozNoiseSuppression: false,\n }\n };\n if (this._device) {\n // @ts-ignore\n constraints.audio.deviceId = this._device.deviceId;\n }\n const stream = yield navigator.mediaDevices.getUserMedia(constraints);\n // start a new source only if the previous one is closed\n if (!this._stream) {\n this._stream = stream;\n // Wrap a MediaStreamSourceNode around the live input stream.\n const mediaStreamNode = this.context.createMediaStreamSource(stream);\n // Connect the MediaStreamSourceNode to a gate gain node\n connect(mediaStreamNode, this.output);\n this._mediaStream = mediaStreamNode;\n }\n return this;\n });\n }\n /**\n * Close the media stream\n */\n close() {\n if (this._stream && this._mediaStream) {\n this._stream.getAudioTracks().forEach((track) => {\n track.stop();\n });\n this._stream = undefined;\n // remove the old media stream\n this._mediaStream.disconnect();\n this._mediaStream = undefined;\n }\n this._device = undefined;\n return this;\n }\n /**\n * Returns a promise which resolves with the list of audio input devices available.\n * @return The promise that is resolved with the devices\n * @example\n * Tone.UserMedia.enumerateDevices().then((devices) => {\n * \t// print the device labels\n * \tconsole.log(devices.map(device => device.label));\n * });\n */\n static enumerateDevices() {\n return __awaiter(this, void 0, void 0, function* () {\n const allDevices = yield navigator.mediaDevices.enumerateDevices();\n return allDevices.filter(device => {\n return device.kind === "audioinput";\n });\n });\n }\n /**\n * Returns the playback state of the source, "started" when the microphone is open\n * and "stopped" when the mic is closed.\n */\n get state() {\n return this._stream && this._stream.active ? "started" : "stopped";\n }\n /**\n * Returns an identifier for the represented device that is\n * persisted across sessions. It is un-guessable by other applications and\n * unique to the origin of the calling application. It is reset when the\n * user clears cookies (for Private Browsing, a different identifier is\n * used that is not persisted across sessions). Returns undefined when the\n * device is not open.\n */\n get deviceId() {\n if (this._device) {\n return this._device.deviceId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a group identifier. Two devices have the\n * same group identifier if they belong to the same physical device.\n * Returns null when the device is not open.\n */\n get groupId() {\n if (this._device) {\n return this._device.groupId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a label describing this device (for example "Built-in Microphone").\n * Returns undefined when the device is not open or label is not available\n * because of permissions.\n */\n get label() {\n if (this._device) {\n return this._device.label;\n }\n else {\n return undefined;\n }\n }\n /**\n * Mute the output.\n * @example\n * const mic = new Tone.UserMedia();\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * });\n * // mute the output\n * mic.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this.close();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n /**\n * If getUserMedia is supported by the browser.\n */\n static get supported() {\n return isDefined(navigator.mediaDevices) &&\n isDefined(navigator.mediaDevices.getUserMedia);\n }\n}\n//# sourceMappingURL=UserMedia.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OscillatorInterface.js\n\n\n/**\n * Render a segment of the oscillator to an offline context and return the results as an array\n */\nfunction generateWaveform(instance, length) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / instance.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, instance.context.sampleRate);\n const clone = new instance.constructor(Object.assign(instance.get(), {\n // should do 2 iterations\n frequency: 2 / duration,\n // zero out the detune\n detune: 0,\n context\n })).toDestination();\n clone.start(0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n}\n//# sourceMappingURL=OscillatorInterface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/ToneOscillatorNode.js\n\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget OscillatorNode.\n * Adds the ability to reschedule the stop method.\n * ***[[Oscillator]] is better for most use-cases***\n * @category Source\n */\nclass ToneOscillatorNode_ToneOscillatorNode extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "ToneOscillatorNode";\n /**\n * The oscillator\n */\n this._oscillator = this.context.createOscillator();\n this._internalChannels = [this._oscillator];\n const options = Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]);\n ToneAudioNode_connect(this._oscillator, this._gainNode);\n this.type = options.type;\n this.frequency = new Param_Param({\n context: this.context,\n param: this._oscillator.frequency,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Param_Param({\n context: this.context,\n param: this._oscillator.detune,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n detune: 0,\n frequency: 440,\n type: "sine",\n });\n }\n /**\n * Start the oscillator node at the given time\n * @param time When to start the oscillator\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._oscillator.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._oscillator.stop(time);\n }\n /**\n * Sets an arbitrary custom periodic waveform given a PeriodicWave.\n * @param periodicWave PeriodicWave should be created with context.createPeriodicWave\n */\n setPeriodicWave(periodicWave) {\n this._oscillator.setPeriodicWave(periodicWave);\n return this;\n }\n /**\n * The oscillator type. Either \'sine\', \'sawtooth\', \'square\', or \'triangle\'\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._oscillator.disconnect();\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneOscillatorNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/Oscillator.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Oscillator supports a number of features including\n * phase rotation, multiple oscillator types (see Oscillator.type),\n * and Transport syncing (see Oscillator.syncFrequency).\n *\n * @example\n * // make and start a 440hz sine tone\n * const osc = new Tone.Oscillator(440, "sine").toDestination().start();\n * @category Source\n */\nclass Oscillator_Oscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "Oscillator";\n /**\n * the main oscillator\n */\n this._oscillator = null;\n const options = Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, "detune");\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n this._type = options.type;\n if (options.partialCount && options.type !== "custom") {\n this._type = this.baseType + options.partialCount.toString();\n }\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n partialCount: 0,\n partials: [],\n phase: 0,\n type: "sine",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n const computedTime = this.toSeconds(time);\n // new oscillator with previous values\n const oscillator = new ToneOscillatorNode_ToneOscillatorNode({\n context: this.context,\n onended: () => this.onstop(this),\n });\n this._oscillator = oscillator;\n if (this._wave) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n else {\n this._oscillator.type = this._type;\n }\n // connect the control signal to the oscillator frequency & detune\n this._oscillator.connect(this.output);\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n // start the oscillator\n this._oscillator.start(computedTime);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n if (this._oscillator) {\n this._oscillator.stop(computedTime);\n }\n }\n /**\n * Restart the oscillator. Does not stop the oscillator, but instead\n * just cancels any scheduled \'stop\' from being invoked.\n */\n _restart(time) {\n const computedTime = this.toSeconds(time);\n this.log("restart", computedTime);\n if (this._oscillator) {\n this._oscillator.cancelStop();\n }\n this._state.cancel(computedTime);\n return this;\n }\n /**\n * Sync the signal to the Transport\'s bpm. Any changes to the transports bpm,\n * will also affect the oscillators frequency.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * osc.frequency.value = 440;\n * // the ratio between the bpm and the frequency will be maintained\n * osc.syncFrequency();\n * // double the tempo\n * Tone.Transport.bpm.value *= 2;\n * // the frequency of the oscillator is doubled to 880\n */\n syncFrequency() {\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the oscillator\'s frequency from the Transport.\n * See Oscillator.syncFrequency\n */\n unsyncFrequency() {\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * Get a cached periodic wave. Avoids having to recompute\n * the oscillator values when they have already been computed\n * with the same values.\n */\n _getCachedPeriodicWave() {\n if (this._type === "custom") {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.phase === this._phase &&\n deepEquals(description.partials, this._partials);\n });\n return oscProps;\n }\n else {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.type === this._type &&\n description.phase === this._phase;\n });\n this._partialCount = oscProps ? oscProps.partialCount : this._partialCount;\n return oscProps;\n }\n }\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n const isBasicType = ["sine", "square", "sawtooth", "triangle"].indexOf(type) !== -1;\n if (this._phase === 0 && isBasicType) {\n this._wave = undefined;\n this._partialCount = 0;\n // just go with the basic approach\n if (this._oscillator !== null) {\n // already tested that it\'s a basic type\n this._oscillator.type = type;\n }\n }\n else {\n // first check if the value is cached\n const cache = this._getCachedPeriodicWave();\n if (TypeCheck_isDefined(cache)) {\n const { partials, wave } = cache;\n this._wave = wave;\n this._partials = partials;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n }\n else {\n const [real, imag] = this._getRealImaginary(type, this._phase);\n const periodicWave = this.context.createPeriodicWave(real, imag);\n this._wave = periodicWave;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n // set the cache\n Oscillator_Oscillator._periodicWaveCache.push({\n imag,\n partialCount: this._partialCount,\n partials: this._partials,\n phase: this._phase,\n real,\n type: this._type,\n wave: this._wave,\n });\n if (Oscillator_Oscillator._periodicWaveCache.length > 100) {\n Oscillator_Oscillator._periodicWaveCache.shift();\n }\n }\n }\n }\n get baseType() {\n return this._type.replace(this.partialCount.toString(), "");\n }\n set baseType(baseType) {\n if (this.partialCount && this._type !== "custom" && baseType !== "custom") {\n this.type = baseType + this.partialCount;\n }\n else {\n this.type = baseType;\n }\n }\n get partialCount() {\n return this._partialCount;\n }\n set partialCount(p) {\n Debug_assertRange(p, 0);\n let type = this._type;\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(this._type);\n if (partial) {\n type = partial[1];\n }\n if (this._type !== "custom") {\n if (p === 0) {\n this.type = type;\n }\n else {\n this.type = type + p.toString();\n }\n }\n else {\n // extend or shorten the partials array\n const fullPartials = new Float32Array(p);\n // copy over the partials array\n this._partials.forEach((v, i) => fullPartials[i] = v);\n this._partials = Array.from(fullPartials);\n this.type = this._type;\n }\n }\n /**\n * Returns the real and imaginary components based\n * on the oscillator type.\n * @returns [real: Float32Array, imaginary: Float32Array]\n */\n _getRealImaginary(type, phase) {\n const fftSize = 4096;\n let periodicWaveSize = fftSize / 2;\n const real = new Float32Array(periodicWaveSize);\n const imag = new Float32Array(periodicWaveSize);\n let partialCount = 1;\n if (type === "custom") {\n partialCount = this._partials.length + 1;\n this._partialCount = this._partials.length;\n periodicWaveSize = partialCount;\n // if the partial count is 0, don\'t bother doing any computation\n if (this._partials.length === 0) {\n return [real, imag];\n }\n }\n else {\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(type);\n if (partial) {\n partialCount = parseInt(partial[2], 10) + 1;\n this._partialCount = parseInt(partial[2], 10);\n type = partial[1];\n partialCount = Math.max(partialCount, 2);\n periodicWaveSize = partialCount;\n }\n else {\n this._partialCount = 0;\n }\n this._partials = [];\n }\n for (let n = 1; n < periodicWaveSize; ++n) {\n const piFactor = 2 / (n * Math.PI);\n let b;\n switch (type) {\n case "sine":\n b = (n <= partialCount) ? 1 : 0;\n this._partials[n - 1] = b;\n break;\n case "square":\n b = (n & 1) ? 2 * piFactor : 0;\n this._partials[n - 1] = b;\n break;\n case "sawtooth":\n b = piFactor * ((n & 1) ? 1 : -1);\n this._partials[n - 1] = b;\n break;\n case "triangle":\n if (n & 1) {\n b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);\n }\n else {\n b = 0;\n }\n this._partials[n - 1] = b;\n break;\n case "custom":\n b = this._partials[n - 1];\n break;\n default:\n throw new TypeError("Oscillator: invalid type: " + type);\n }\n if (b !== 0) {\n real[n] = -b * Math.sin(phase * n);\n imag[n] = b * Math.cos(phase * n);\n }\n else {\n real[n] = 0;\n imag[n] = 0;\n }\n }\n return [real, imag];\n }\n /**\n * Compute the inverse FFT for a given phase.\n */\n _inverseFFT(real, imag, phase) {\n let sum = 0;\n const len = real.length;\n for (let i = 0; i < len; i++) {\n sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase);\n }\n return sum;\n }\n /**\n * Returns the initial value of the oscillator when stopped.\n * E.g. a "sine" oscillator with phase = 90 would return an initial value of -1.\n */\n getInitialValue() {\n const [real, imag] = this._getRealImaginary(this._type, 0);\n let maxValue = 0;\n const twoPi = Math.PI * 2;\n const testPositions = 32;\n // check for peaks in 16 places\n for (let i = 0; i < testPositions; i++) {\n maxValue = Math.max(this._inverseFFT(real, imag, (i / testPositions) * twoPi), maxValue);\n }\n return Math_clamp(-this._inverseFFT(real, imag, this._phase) / maxValue, -1, 1);\n }\n get partials() {\n return this._partials.slice(0, this.partialCount);\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this.type = "custom";\n }\n }\n get phase() {\n return this._phase * (180 / Math.PI);\n }\n set phase(phase) {\n this._phase = phase * Math.PI / 180;\n // reset the type\n this.type = this._type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n if (this._oscillator !== null) {\n this._oscillator.dispose();\n }\n this._wave = undefined;\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n/**\n * Cache the periodic waves to avoid having to redo computations\n */\nOscillator_Oscillator._periodicWaveCache = [];\n//# sourceMappingURL=Oscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SignalOperator.js\n\n\n\n/**\n * A signal operator has an input and output and modifies the signal.\n */\nclass SignalOperator_SignalOperator extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(SignalOperator_SignalOperator.getDefaults(), arguments, ["context"])));\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n}\n//# sourceMappingURL=SignalOperator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/WaveShaper.js\n\n\n\n\n\n/**\n * Wraps the native Web Audio API\n * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // multiply the output of the signal by 2 using the waveshaper\'s function\n * const timesTwo = new Tone.WaveShaper((val) => val * 2, 2048).connect(osc.frequency);\n * const signal = new Tone.Signal(440).connect(timesTwo);\n * @category Signal\n */\nclass WaveShaper_WaveShaper extends SignalOperator_SignalOperator {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"])));\n this.name = "WaveShaper";\n /**\n * the waveshaper node\n */\n this._shaper = this.context.createWaveShaper();\n /**\n * The input to the waveshaper node.\n */\n this.input = this._shaper;\n /**\n * The output from the waveshaper node\n */\n this.output = this._shaper;\n const options = Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"]);\n if (TypeCheck_isArray(options.mapping) || options.mapping instanceof Float32Array) {\n this.curve = Float32Array.from(options.mapping);\n }\n else if (isFunction(options.mapping)) {\n this.setMap(options.mapping, options.length);\n }\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n length: 1024,\n });\n }\n /**\n * Uses a mapping function to set the value of the curve.\n * @param mapping The function used to define the values.\n * The mapping function take two arguments:\n * the first is the value at the current position\n * which goes from -1 to 1 over the number of elements\n * in the curve array. The second argument is the array position.\n * @example\n * const shaper = new Tone.WaveShaper();\n * // map the input signal from [-1, 1] to [0, 10]\n * shaper.setMap((val, index) => (val + 1) * 5);\n */\n setMap(mapping, length = 1024) {\n const array = new Float32Array(length);\n for (let i = 0, len = length; i < len; i++) {\n const normalized = (i / (len - 1)) * 2 - 1;\n array[i] = mapping(normalized, i);\n }\n this.curve = array;\n return this;\n }\n /**\n * The array to set as the waveshaper curve. For linear curves\n * array length does not make much difference, but for complex curves\n * longer arrays will provide smoother interpolation.\n */\n get curve() {\n return this._shaper.curve;\n }\n set curve(mapping) {\n this._shaper.curve = mapping;\n }\n /**\n * Specifies what type of oversampling (if any) should be used when\n * applying the shaping curve. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n const isOverSampleType = ["none", "2x", "4x"].some(str => str.includes(oversampling));\n Debug_assert(isOverSampleType, "oversampling must be either \'none\', \'2x\', or \'4x\'");\n this._shaper.oversample = oversampling;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._shaper.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=WaveShaper.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/AudioToGain.js\n\n\n/**\n * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1].\n * See [[GainToAudio]].\n * @category Signal\n */\nclass AudioToGain_AudioToGain extends SignalOperator_SignalOperator {\n constructor() {\n super(...arguments);\n this.name = "AudioToGain";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: x => (x + 1) / 2,\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._norm;\n /**\n * The GainRange output [0, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AudioToGain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Multiply.js\n\n\n\n/**\n * Multiply two incoming signals. Or, if a number is given in the constructor,\n * multiplies the incoming signal by that value.\n *\n * @example\n * // multiply two signals\n * const mult = new Tone.Multiply();\n * const sigA = new Tone.Signal(3);\n * const sigB = new Tone.Signal(4);\n * sigA.connect(mult);\n * sigB.connect(mult.factor);\n * // output of mult is 12.\n * @example\n * // multiply a signal and a number\n * const mult = new Tone.Multiply(10);\n * const sig = new Tone.Signal(2).connect(mult);\n * // the output of mult is 20.\n * @category Signal\n */\nclass Multiply_Multiply extends Signal_Signal {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"])));\n this.name = "Multiply";\n /**\n * Indicates if the value should be overridden on connection\n */\n this.override = false;\n const options = Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"]);\n this._mult = this.input = this.output = new Gain_Gain({\n context: this.context,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this.factor = this._param = this._mult.gain;\n this.factor.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Multiply.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/AMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * An amplitude modulated oscillator node. It is implemented with\n * two oscillators, one which modulators the other\'s amplitude\n * through a gain node.\n * ```\n * +-------------+ +----------+\n * | Carrier Osc +>------\x3e GainNode |\n * +-------------+ | +---\x3eOutput\n * +---\x3e gain |\n * +---------------+ | +----------+\n * | Modulator Osc +>---+\n * +---------------+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst amOsc = new Tone.AMOscillator(30, "sine", "square").toDestination().start();\n * }, 0.2, 1);\n * @category Source\n */\nclass AMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "AMOscillator";\n /**\n * convert the -1,1 output to 0,1\n */\n this._modulationScale = new AudioToGain_AudioToGain({ context: this.context });\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n });\n const options = Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.frequency = this._carrier.frequency,\n this.detune = this._carrier.detune;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n // connections\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n Interface_readOnly(this, ["frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n }\n /**\n * The type of the carrier oscillator\n */\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * FMOscillator implements a frequency modulation synthesis\n * ```\n * +-------------+\n * +---------------+ +-------------+ | Carrier Osc |\n * | Modulator Osc +>-------\x3e GainNode | | +---\x3eOutput\n * +---------------+ | +>----\x3e frequency |\n * +--\x3e gain | +-------------+\n * | +-------------+\n * +-----------------+ |\n * | modulationIndex +>--+\n * +-----------------+\n * ```\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst fmOsc = new Tone.FMOscillator({\n * \t\tfrequency: 200,\n * \t\ttype: "square",\n * \t\tmodulationType: "triangle",\n * \t\tharmonicity: 0.2,\n * \t\tmodulationIndex: 3\n * \t}).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass FMOscillator_FMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "FMOscillator";\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n const options = Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: 0,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.detune = this._carrier.detune;\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this.modulationIndex = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.modulationIndex,\n });\n // connections\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n this.detune.connect(this._modulator.detune);\n Interface_readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationIndex: 2,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n return this;\n }\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PulseOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * PulseOscillator is an oscillator with control over pulse width,\n * also known as the duty cycle. At 50% duty cycle (width = 0) the wave is\n * a square wave.\n * [Read more](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).\n * ```\n * width = -0.25 width = 0.0 width = 0.25\n *\n * +-----+ +-------+ + +-------+ +-+\n * | | | | | | |\n * | | | | | | |\n * +-+ +-------+ + +-------+ +-----+\n *\n *\n * width = -0.5 width = 0.5\n *\n * +---+ +-------+ +---+\n * | | | |\n * | | | |\n * +---+ +-------+ +---+\n *\n *\n * width = -0.75 width = 0.75\n *\n * +-+ +-------+ +-----+\n * | | | |\n * | | | |\n * +-----+ +-------+ +-+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst pulse = new Tone.PulseOscillator(50, 0.4).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PulseOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]));\n this.name = "PulseOscillator";\n /**\n * gate the width amount\n */\n this._widthGate = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * Threshold the signal to turn it into a square\n */\n this._thresh = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: val => val <= 0 ? -1 : 1,\n });\n const options = Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]);\n this.width = new Signal_Signal({\n context: this.context,\n units: "audioRange",\n value: options.width,\n });\n this._triangle = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: "triangle",\n });\n this.frequency = this._triangle.frequency;\n this.detune = this._triangle.detune;\n // connections\n this._triangle.chain(this._thresh, this.output);\n this.width.chain(this._widthGate, this._thresh);\n Interface_readOnly(this, ["width", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n phase: 0,\n type: "pulse",\n width: 0.2,\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._triangle.start(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._triangle.stop(time);\n // the width is still connected to the output.\n // that needs to be stopped also\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(0, time);\n }\n _restart(time) {\n this._triangle.restart(time);\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._triangle.phase;\n }\n set phase(phase) {\n this._triangle.phase = phase;\n }\n /**\n * The type of the oscillator. Always returns "pulse".\n */\n get type() {\n return "pulse";\n }\n /**\n * The baseType of the oscillator. Always returns "pulse".\n */\n get baseType() {\n return "pulse";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * *Internal use* The carrier oscillator type is fed through the\n * waveshaper node to create the pulse. Using different carrier oscillators\n * changes oscillator\'s behavior.\n */\n set carrierType(type) {\n this._triangle.type = type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up method.\n */\n dispose() {\n super.dispose();\n this._triangle.dispose();\n this.width.dispose();\n this._widthGate.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PulseOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FatOscillator.js\n\n\n\n\n\n\n\n\n/**\n * FatOscillator is an array of oscillators with detune spread between the oscillators\n * @example\n * const fatOsc = new Tone.FatOscillator("Ab3", "sawtooth", 40).toDestination().start();\n * @category Source\n */\nclass FatOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]));\n this.name = "FatOscillator";\n /**\n * The array of oscillators\n */\n this._oscillators = [];\n const options = Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this._spread = options.spread;\n this._type = options.type;\n this._phase = options.phase;\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n // set the count initially\n this.count = options.count;\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n count: 3,\n spread: 20,\n type: "sawtooth",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.start(time));\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.stop(time));\n }\n _restart(time) {\n this._forEach(osc => osc.restart(time));\n }\n /**\n * Iterate over all of the oscillators\n */\n _forEach(iterator) {\n for (let i = 0; i < this._oscillators.length; i++) {\n iterator(this._oscillators[i], i);\n }\n }\n /**\n * The type of the oscillator\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n this._forEach(osc => osc.type = type);\n }\n /**\n * The detune spread between the oscillators. If "count" is\n * set to 3 oscillators and the "spread" is set to 40,\n * the three oscillators would be detuned like this: [-20, 0, 20]\n * for a total detune spread of 40 cents.\n * @example\n * const fatOsc = new Tone.FatOscillator().toDestination().start();\n * fatOsc.spread = 70;\n */\n get spread() {\n return this._spread;\n }\n set spread(spread) {\n this._spread = spread;\n if (this._oscillators.length > 1) {\n const start = -spread / 2;\n const step = spread / (this._oscillators.length - 1);\n this._forEach((osc, i) => osc.detune.value = start + step * i);\n }\n }\n /**\n * The number of detuned oscillators. Must be an integer greater than 1.\n * @example\n * const fatOsc = new Tone.FatOscillator("C#3", "sawtooth").toDestination().start();\n * // use 4 sawtooth oscillators\n * fatOsc.count = 4;\n */\n get count() {\n return this._oscillators.length;\n }\n set count(count) {\n Debug_assertRange(count, 1);\n if (this._oscillators.length !== count) {\n // dispose the previous oscillators\n this._forEach(osc => osc.dispose());\n this._oscillators = [];\n for (let i = 0; i < count; i++) {\n const osc = new Oscillator_Oscillator({\n context: this.context,\n volume: -6 - count * 1.1,\n type: this._type,\n phase: this._phase + (i / count) * 360,\n partialCount: this._partialCount,\n onstop: i === 0 ? () => this.onstop(this) : Interface_noOp,\n });\n if (this.type === "custom") {\n osc.partials = this._partials;\n }\n this.frequency.connect(osc.frequency);\n this.detune.connect(osc.detune);\n osc.detune.overridden = false;\n osc.connect(this.output);\n this._oscillators[i] = osc;\n }\n // set the spread\n this.spread = this._spread;\n if (this.state === "started") {\n this._forEach(osc => osc.start());\n }\n }\n }\n get phase() {\n return this._phase;\n }\n set phase(phase) {\n this._phase = phase;\n this._forEach((osc, i) => osc.phase = this._phase + (i / this.count) * 360);\n }\n get baseType() {\n return this._oscillators[0].baseType;\n }\n set baseType(baseType) {\n this._forEach(osc => osc.baseType = baseType);\n this._type = this._oscillators[0].type;\n }\n get partials() {\n return this._oscillators[0].partials;\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this._type = "custom";\n this._forEach(osc => osc.partials = partials);\n }\n }\n get partialCount() {\n return this._oscillators[0].partialCount;\n }\n set partialCount(partialCount) {\n this._partialCount = partialCount;\n this._forEach(osc => osc.partialCount = partialCount);\n this._type = this._oscillators[0].type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._forEach(osc => osc.dispose());\n return this;\n }\n}\n//# sourceMappingURL=FatOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PWMOscillator.js\n\n\n\n\n\n\n\n\n/**\n * PWMOscillator modulates the width of a Tone.PulseOscillator\n * at the modulationFrequency. This has the effect of continuously\n * changing the timbre of the oscillator by altering the harmonics\n * generated.\n * @example\n * return Tone.Offline(() => {\n * \tconst pwm = new Tone.PWMOscillator(60, 0.3).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PWMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]));\n this.name = "PWMOscillator";\n this.sourceType = "pwm";\n /**\n * Scale the oscillator so it doesn\'t go silent\n * at the extreme values.\n */\n this._scale = new Multiply_Multiply({\n context: this.context,\n value: 2,\n });\n const options = Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]);\n this._pulse = new PulseOscillator({\n context: this.context,\n frequency: options.modulationFrequency,\n });\n // change the pulse oscillator type\n this._pulse.carrierType = "sine";\n this.modulationFrequency = this._pulse.frequency;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n });\n this.frequency = this._modulator.frequency;\n this.detune = this._modulator.detune;\n // connections\n this._modulator.chain(this._scale, this._pulse.width);\n this._pulse.connect(this.output);\n Interface_readOnly(this, ["modulationFrequency", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n modulationFrequency: 0.4,\n phase: 0,\n type: "pwm",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._modulator.start(time);\n this._pulse.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._modulator.stop(time);\n this._pulse.stop(time);\n }\n /**\n * restart the oscillator\n */\n _restart(time) {\n this._modulator.restart(time);\n this._pulse.restart(time);\n }\n /**\n * The type of the oscillator. Always returns "pwm".\n */\n get type() {\n return "pwm";\n }\n /**\n * The baseType of the oscillator. Always returns "pwm".\n */\n get baseType() {\n return "pwm";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._modulator.phase;\n }\n set phase(phase) {\n this._modulator.phase = phase;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._pulse.dispose();\n this._scale.dispose();\n this._modulator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PWMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OmniOscillator.js\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst OmniOscillatorSourceMap = {\n am: AMOscillator,\n fat: FatOscillator,\n fm: FMOscillator_FMOscillator,\n oscillator: Oscillator_Oscillator,\n pulse: PulseOscillator,\n pwm: PWMOscillator,\n};\n/**\n * OmniOscillator aggregates all of the oscillator types into one.\n * @example\n * return Tone.Offline(() => {\n * \tconst omniOsc = new Tone.OmniOscillator("C#4", "pwm").toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass OmniOscillator_OmniOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OmniOscillator";\n const options = Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n // set the options\n this.set(options);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), FMOscillator_FMOscillator.getDefaults(), AMOscillator.getDefaults(), FatOscillator.getDefaults(), PulseOscillator.getDefaults(), PWMOscillator.getDefaults());\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._oscillator.start(time);\n }\n /**\n * start the oscillator\n */\n _stop(time) {\n this._oscillator.stop(time);\n }\n _restart(time) {\n this._oscillator.restart(time);\n return this;\n }\n /**\n * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or\n * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator\n * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the\n * oscillator\'s class are accessible when the oscillator is set to that type, but throws an error\n * when it\'s not.\n * @example\n * const omniOsc = new Tone.OmniOscillator().toDestination().start();\n * omniOsc.type = "pwm";\n * // modulationFrequency is parameter which is available\n * // only when the type is "pwm".\n * omniOsc.modulationFrequency.value = 0.5;\n */\n get type() {\n let prefix = "";\n if (["am", "fm", "fat"].some(p => this._sourceType === p)) {\n prefix = this._sourceType;\n }\n return prefix + this._oscillator.type;\n }\n set type(type) {\n if (type.substr(0, 2) === "fm") {\n this._createNewOscillator("fm");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 2) === "am") {\n this._createNewOscillator("am");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 3) === "fat") {\n this._createNewOscillator("fat");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(3);\n }\n else if (type === "pwm") {\n this._createNewOscillator("pwm");\n this._oscillator = this._oscillator;\n }\n else if (type === "pulse") {\n this._createNewOscillator("pulse");\n }\n else {\n this._createNewOscillator("oscillator");\n this._oscillator = this._oscillator;\n this._oscillator.type = type;\n }\n }\n /**\n * The value is an empty array when the type is not "custom".\n * This is not available on "pwm" and "pulse" oscillator types.\n * See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partials = partials;\n }\n }\n get partialCount() {\n return this._oscillator.partialCount;\n }\n set partialCount(partialCount) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partialCount = partialCount;\n }\n }\n set(props) {\n // make sure the type is set first\n if (Reflect.has(props, "type") && props.type) {\n this.type = props.type;\n }\n // then set the rest\n super.set(props);\n return this;\n }\n /**\n * connect the oscillator to the frequency and detune signals\n */\n _createNewOscillator(oscType) {\n if (oscType !== this._sourceType) {\n this._sourceType = oscType;\n const OscConstructor = OmniOscillatorSourceMap[oscType];\n // short delay to avoid clicks on the change\n const now = this.now();\n if (this._oscillator) {\n const oldOsc = this._oscillator;\n oldOsc.stop(now);\n // dispose the old one\n this.context.setTimeout(() => oldOsc.dispose(), this.blockTime);\n }\n this._oscillator = new OscConstructor({\n context: this.context,\n });\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n this._oscillator.connect(this.output);\n this._oscillator.onstop = () => this.onstop(this);\n if (this.state === "started") {\n this._oscillator.start(now);\n }\n }\n }\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n }\n /**\n * The source type of the oscillator.\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare");\n * console.log(omniOsc.sourceType); // \'fm\'\n */\n get sourceType() {\n return this._sourceType;\n }\n set sourceType(sType) {\n // the basetype defaults to sine\n let baseType = "sine";\n if (this._oscillator.type !== "pwm" && this._oscillator.type !== "pulse") {\n baseType = this._oscillator.type;\n }\n // set the type\n if (sType === "fm") {\n this.type = "fm" + baseType;\n }\n else if (sType === "am") {\n this.type = "am" + baseType;\n }\n else if (sType === "fat") {\n this.type = "fat" + baseType;\n }\n else if (sType === "oscillator") {\n this.type = baseType;\n }\n else if (sType === "pulse") {\n this.type = "pulse";\n }\n else if (sType === "pwm") {\n this.type = "pwm";\n }\n }\n _getOscType(osc, sourceType) {\n return osc instanceof OmniOscillatorSourceMap[sourceType];\n }\n /**\n * The base type of the oscillator. See [[Oscillator.baseType]]\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4");\n * console.log(omniOsc.sourceType, omniOsc.baseType, omniOsc.partialCount);\n */\n get baseType() {\n return this._oscillator.baseType;\n }\n set baseType(baseType) {\n if (!this._getOscType(this._oscillator, "pulse") &&\n !this._getOscType(this._oscillator, "pwm") &&\n baseType !== "pulse" && baseType !== "pwm") {\n this._oscillator.baseType = baseType;\n }\n }\n /**\n * The width of the oscillator when sourceType === "pulse".\n * See [[PWMOscillator.width]]\n */\n get width() {\n if (this._getOscType(this._oscillator, "pulse")) {\n return this._oscillator.width;\n }\n else {\n return undefined;\n }\n }\n /**\n * The number of detuned oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get count() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.count;\n }\n else {\n return undefined;\n }\n }\n set count(count) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(count)) {\n this._oscillator.count = count;\n }\n }\n /**\n * The detune spread between the oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get spread() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.spread;\n }\n else {\n return undefined;\n }\n }\n set spread(spread) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(spread)) {\n this._oscillator.spread = spread;\n }\n }\n /**\n * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get modulationType() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.modulationType;\n }\n else {\n return undefined;\n }\n }\n set modulationType(mType) {\n if ((this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) && TypeCheck_isString(mType)) {\n this._oscillator.modulationType = mType;\n }\n }\n /**\n * The modulation index when the sourceType === "fm"\n * See [[FMOscillator]].\n */\n get modulationIndex() {\n if (this._getOscType(this._oscillator, "fm")) {\n return this._oscillator.modulationIndex;\n }\n else {\n return undefined;\n }\n }\n /**\n * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get harmonicity() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.harmonicity;\n }\n else {\n return undefined;\n }\n }\n /**\n * The modulationFrequency Signal of the oscillator when sourceType === "pwm"\n * see [[PWMOscillator]]\n * @min 0.1\n * @max 5\n */\n get modulationFrequency() {\n if (this._getOscType(this._oscillator, "pwm")) {\n return this._oscillator.modulationFrequency;\n }\n else {\n return undefined;\n }\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n this.detune.dispose();\n this.frequency.dispose();\n this._oscillator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=OmniOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Add.js\n\n\n\n\n/**\n * Add a signal and a number or two signals. When no value is\n * passed into the constructor, Tone.Add will sum input and `addend`\n * If a value is passed into the constructor, the it will be added to the input.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst add = new Tone.Add(2).toDestination();\n * \tadd.addend.setValueAtTime(1, 0.2);\n * \tconst signal = new Tone.Signal(2);\n * \t// add a signal and a scalar\n * \tsignal.connect(add);\n * \tsignal.setValueAtTime(1, 0.1);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Add_Add extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Add_Add.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Add";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * The value which is added to the input signal\n */\n this.addend = this._param;\n connectSeries(this._constantSource, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Add.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Scale.js\n\n\n\n\n/**\n * Performs a linear scaling on an input signal.\n * Scales a NormalRange input to between\n * outputMin and outputMax.\n *\n * @example\n * const scale = new Tone.Scale(50, 100);\n * const signal = new Tone.Signal(0.5).connect(scale);\n * // the output of scale equals 75\n * @category Signal\n */\nclass Scale_Scale extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"])));\n this.name = "Scale";\n const options = optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"]);\n this._mult = this.input = new Multiply({\n context: this.context,\n value: options.max - options.min,\n });\n this._add = this.output = new Add({\n context: this.context,\n value: options.min,\n });\n this._min = options.min;\n this._max = options.max;\n this.input.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n max: 1,\n min: 0,\n });\n }\n /**\n * The minimum output value. This number is output when the value input value is 0.\n */\n get min() {\n return this._min;\n }\n set min(min) {\n this._min = min;\n this._setRange();\n }\n /**\n * The maximum output value. This number is output when the value input value is 1.\n */\n get max() {\n return this._max;\n }\n set max(max) {\n this._max = max;\n this._setRange();\n }\n /**\n * set the values\n */\n _setRange() {\n this._add.value = this._min;\n this._mult.value = this._max - this._min;\n }\n dispose() {\n super.dispose();\n this._add.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Scale.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Zero.js\n\n\n\n\n/**\n * Tone.Zero outputs 0\'s at audio-rate. The reason this has to be\n * it\'s own class is that many browsers optimize out Tone.Signal\n * with a value of 0 and will not process nodes further down the graph.\n * @category Signal\n */\nclass Zero_Zero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Zero_Zero.getDefaults(), arguments)));\n this.name = "Zero";\n /**\n * The gain node which connects the constant source to the output\n */\n this._gain = new Gain({ context: this.context });\n /**\n * Only outputs 0\n */\n this.output = this._gain;\n /**\n * no input node\n */\n this.input = undefined;\n connect(this.context.getConstant(0), this._gain);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n disconnect(this.context.getConstant(0), this._gain);\n return this;\n }\n}\n//# sourceMappingURL=Zero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/LFO.js\n\n\n\n\n\n\n\n\n\n\n/**\n * LFO stands for low frequency oscillator. LFO produces an output signal\n * which can be attached to an AudioParam or Tone.Signal\n * in order to modulate that parameter with an oscillator. The LFO can\n * also be synced to the transport to start/stop and change when the tempo changes.\n * @example\n * return Tone.Offline(() => {\n * \tconst lfo = new Tone.LFO("4n", 400, 4000).start().toDestination();\n * }, 0.5, 1);\n * @category Source\n */\nclass LFO_LFO extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]));\n this.name = "LFO";\n /**\n * The value that the LFO outputs when it\'s stopped\n */\n this._stoppedValue = 0;\n /**\n * A private placeholder for the units\n */\n this._units = "number";\n /**\n * If the input value is converted using the [[units]]\n */\n this.convert = true;\n /**\n * Private methods borrowed from Param\n */\n // @ts-ignore\n this._fromType = Param.prototype._fromType;\n // @ts-ignore\n this._toType = Param.prototype._toType;\n // @ts-ignore\n this._is = Param.prototype._is;\n // @ts-ignore\n this._clampValue = Param.prototype._clampValue;\n const options = optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]);\n this._oscillator = new Oscillator(options);\n this.frequency = this._oscillator.frequency;\n this._amplitudeGain = new Gain({\n context: this.context,\n gain: options.amplitude,\n units: "normalRange",\n });\n this.amplitude = this._amplitudeGain.gain;\n this._stoppedSignal = new Signal({\n context: this.context,\n units: "audioRange",\n value: 0,\n });\n this._zeros = new Zero({ context: this.context });\n this._a2g = new AudioToGain({ context: this.context });\n this._scaler = this.output = new Scale({\n context: this.context,\n max: options.max,\n min: options.min,\n });\n this.units = options.units;\n this.min = options.min;\n this.max = options.max;\n // connect it up\n this._oscillator.chain(this._amplitudeGain, this._a2g, this._scaler);\n this._zeros.connect(this._a2g);\n this._stoppedSignal.connect(this._a2g);\n readOnly(this, ["amplitude", "frequency"]);\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Oscillator.getDefaults(), {\n amplitude: 1,\n frequency: "4n",\n max: 1,\n min: 0,\n type: "sine",\n units: "number",\n });\n }\n /**\n * Start the LFO.\n * @param time The time the LFO will start\n */\n start(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(0, time);\n this._oscillator.start(time);\n return this;\n }\n /**\n * Stop the LFO.\n * @param time The time the LFO will stop\n */\n stop(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(this._stoppedValue, time);\n this._oscillator.stop(time);\n return this;\n }\n /**\n * Sync the start/stop/pause to the transport\n * and the frequency to the bpm of the transport\n * @example\n * const lfo = new Tone.LFO("8n");\n * lfo.sync().start(0);\n * // the rate of the LFO will always be an eighth note, even as the tempo changes\n */\n sync() {\n this._oscillator.sync();\n this._oscillator.syncFrequency();\n return this;\n }\n /**\n * unsync the LFO from transport control\n */\n unsync() {\n this._oscillator.unsync();\n this._oscillator.unsyncFrequency();\n return this;\n }\n /**\n * After the oscillator waveform is updated, reset the `_stoppedSignal` value to match the updated waveform\n */\n _setStoppedValue() {\n this._stoppedValue = this._oscillator.getInitialValue();\n this._stoppedSignal.value = this._stoppedValue;\n }\n /**\n * The minimum output of the LFO.\n */\n get min() {\n return this._toType(this._scaler.min);\n }\n set min(min) {\n min = this._fromType(min);\n this._scaler.min = min;\n }\n /**\n * The maximum output of the LFO.\n */\n get max() {\n return this._toType(this._scaler.max);\n }\n set max(max) {\n max = this._fromType(max);\n this._scaler.max = max;\n }\n /**\n * The type of the oscillator: See [[Oscillator.type]]\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n this._setStoppedValue();\n }\n /**\n * The oscillator\'s partials array: See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n this._oscillator.partials = partials;\n this._setStoppedValue();\n }\n /**\n * The phase of the LFO.\n */\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n this._setStoppedValue();\n }\n /**\n * The output units of the LFO.\n */\n get units() {\n return this._units;\n }\n set units(val) {\n const currentMin = this.min;\n const currentMax = this.max;\n // convert the min and the max\n this._units = val;\n this.min = currentMin;\n this.max = currentMax;\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n */\n get state() {\n return this._oscillator.state;\n }\n /**\n * @param node the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\n connect(node, outputNum, inputNum) {\n if (node instanceof Param || node instanceof Signal) {\n this.convert = node.convert;\n this.units = node.units;\n }\n connectSignal(this, node, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._oscillator.dispose();\n this._stoppedSignal.dispose();\n this._zeros.dispose();\n this._scaler.dispose();\n this._a2g.dispose();\n this._amplitudeGain.dispose();\n this.amplitude.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFO.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Decorator.js\n\n/**\n * Assert that the number is in the given range.\n */\nfunction range(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(newValue, min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n/**\n * Convert the time to seconds and assert that the time is in between the two\n * values when being set.\n */\nfunction timeRange(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(this.toSeconds(newValue), min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n//# sourceMappingURL=Decorator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Player.js\n\n\n\n\n\n\n\n\n\n/**\n * Player is an audio file player with start, loop, and stop functions.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n * @category Source\n */\nclass Player_Player extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Player";\n /**\n * All of the active buffer source nodes\n */\n this._activeSources = new Set();\n const options = Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer({\n onload: this._onload.bind(this, options.onload),\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this.autostart = options.autostart;\n this._loop = options.loop;\n this._loopStart = options.loopStart;\n this._loopEnd = options.loopEnd;\n this._playbackRate = options.playbackRate;\n this.fadeIn = options.fadeIn;\n this.fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n autostart: false,\n fadeIn: 0,\n fadeOut: 0,\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n reverse: false,\n });\n }\n /**\n * Load the audio file as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * Note: this does not need to be called if a url\n * was passed in to the constructor. Only use this\n * if you want to manually load a new url.\n * @param url The url of the buffer to load. Filetype support depends on the browser.\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this._buffer.load(url);\n this._onload();\n return this;\n });\n }\n /**\n * Internal callback when the buffer is loaded.\n */\n _onload(callback = Interface_noOp) {\n callback();\n if (this.autostart) {\n this.start();\n }\n }\n /**\n * Internal callback when the buffer is done playing.\n */\n _onSourceEnd(source) {\n // invoke the onstop function\n this.onstop(this);\n // delete the source from the active sources\n this._activeSources.delete(source);\n if (this._activeSources.size === 0 && !this._synced &&\n this._state.getValueAtTime(this.now()) === "started") {\n // remove the \'implicitEnd\' event and replace with an explicit end\n this._state.cancel(this.now());\n this._state.setStateAtTime("stopped", this.now());\n }\n }\n /**\n * Play the buffer at the given startTime. Optionally add an offset\n * and/or duration which will play the buffer from a position\n * within the buffer for the given duration.\n *\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n */\n start(time, offset, duration) {\n super.start(time, offset, duration);\n return this;\n }\n /**\n * Internal start method\n */\n _start(startTime, offset, duration) {\n // if it\'s a loop the default offset is the loopStart point\n if (this._loop) {\n offset = Defaults_defaultArg(offset, this._loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // compute the values in seconds\n const computedOffset = this.toSeconds(offset);\n // compute the duration which is either the passed in duration of the buffer.duration - offset\n const origDuration = duration;\n duration = Defaults_defaultArg(duration, Math.max(this._buffer.duration - computedOffset, 0));\n let computedDuration = this.toSeconds(duration);\n // scale it by the playback rate\n computedDuration = computedDuration / this._playbackRate;\n // get the start time\n startTime = this.toSeconds(startTime);\n // make the source\n const source = new ToneBufferSource_ToneBufferSource({\n url: this._buffer,\n context: this.context,\n fadeIn: this.fadeIn,\n fadeOut: this.fadeOut,\n loop: this._loop,\n loopEnd: this._loopEnd,\n loopStart: this._loopStart,\n onended: this._onSourceEnd.bind(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n // set the looping properties\n if (!this._loop && !this._synced) {\n // cancel the previous stop\n this._state.cancel(startTime + computedDuration);\n // if it\'s not looping, set the state change at the end of the sample\n this._state.setStateAtTime("stopped", startTime + computedDuration, {\n implicitEnd: true,\n });\n }\n // add it to the array of active sources\n this._activeSources.add(source);\n // start it\n if (this._loop && TypeCheck_isUndef(origDuration)) {\n source.start(startTime, computedOffset);\n }\n else {\n // subtract the fade out time\n source.start(startTime, computedOffset, computedDuration - this.toSeconds(this.fadeOut));\n }\n }\n /**\n * Stop playback.\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(source => source.stop(computedTime));\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Seek to a specific time in the player\'s buffer. If the\n * source is no longer playing at that time, it will stop.\n * @param offset The time to seek to.\n * @param when The time for the seek event to occur.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3", () => {\n * \tplayer.start();\n * \t// seek to the offset in 1 second from now\n * \tplayer.seek(0.4, "+1");\n * }).toDestination();\n */\n seek(offset, when) {\n const computedTime = this.toSeconds(when);\n if (this._state.getValueAtTime(computedTime) === "started") {\n const computedOffset = this.toSeconds(offset);\n // if it\'s currently playing, stop it\n this._stop(computedTime);\n // restart it at the given time\n this._start(computedTime, computedOffset);\n }\n return this;\n }\n /**\n * Set the loop start and end. Will only loop if loop is set to true.\n * @param loopStart The loop start time\n * @param loopEnd The loop end time\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/malevoices_aa2_F3.mp3").toDestination();\n * // loop between the given points\n * player.setLoopPoints(0.2, 0.3);\n * player.loop = true;\n * player.autostart = true;\n */\n setLoopPoints(loopStart, loopEnd) {\n this.loopStart = loopStart;\n this.loopEnd = loopEnd;\n return this;\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(loopStart) {\n this._loopStart = loopStart;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopStart), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopStart = loopStart;\n });\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(loopEnd) {\n this._loopEnd = loopEnd;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopEnd), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopEnd = loopEnd;\n });\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/breakbeat.mp3").toDestination();\n * player.loop = true;\n * player.autostart = true;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n // if no change, do nothing\n if (this._loop === loop) {\n return;\n }\n this._loop = loop;\n // set the loop of all of the sources\n this._activeSources.forEach(source => {\n source.loop = loop;\n });\n if (loop) {\n // remove the next stopEvent\n const stopEvent = this._state.getNextState("stopped", this.now());\n if (stopEvent) {\n this._state.cancel(stopEvent.time);\n }\n }\n }\n /**\n * Normal speed is 1. The pitch will change with the playback rate.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/femalevoices_aa2_A5.mp3").toDestination();\n * // play at 1/4 speed\n * player.playbackRate = 0.25;\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n const now = this.now();\n // cancel the stop event since it\'s at a different time now\n const stopEvent = this._state.getNextState("stopped", now);\n if (stopEvent && stopEvent.implicitEnd) {\n this._state.cancel(stopEvent.time);\n this._activeSources.forEach(source => source.cancelStop());\n }\n // set all the sources\n this._activeSources.forEach(source => {\n source.playbackRate.setValueAtTime(rate, now);\n });\n }\n /**\n * If the buffer should be reversed\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/chime_1.mp3").toDestination();\n * player.autostart = true;\n * player.reverse = true;\n */\n get reverse() {\n return this._buffer.reverse;\n }\n set reverse(rev) {\n this._buffer.reverse = rev;\n }\n /**\n * If the buffer is loaded\n */\n get loaded() {\n return this._buffer.loaded;\n }\n dispose() {\n super.dispose();\n // disconnect all of the players\n this._activeSources.forEach(source => source.dispose());\n this._activeSources.clear();\n this._buffer.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeIn", void 0);\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeOut", void 0);\n//# sourceMappingURL=Player.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Players.js\n\n\n\n\n\n\n\n\n/**\n * Players combines multiple [[Player]] objects.\n * @category Source\n */\nclass Players extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls"));\n this.name = "Players";\n /**\n * Players has no input.\n */\n this.input = undefined;\n /**\n * The container of all of the players\n */\n this._players = new Map();\n const options = optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls");\n /**\n * The output volume node\n */\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this._buffers = new ToneAudioBuffers({\n urls: options.urls,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror\n });\n // mute initially\n this.mute = options.mute;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n baseUrl: "",\n fadeIn: 0,\n fadeOut: 0,\n mute: false,\n onload: noOp,\n onerror: noOp,\n urls: {},\n volume: 0,\n });\n }\n /**\n * Mute the output.\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * The fadeIn time of the envelope applied to the source.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(fadeIn) {\n this._fadeIn = fadeIn;\n this._players.forEach(player => {\n player.fadeIn = fadeIn;\n });\n }\n /**\n * The fadeOut time of the each of the sources.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(fadeOut) {\n this._fadeOut = fadeOut;\n this._players.forEach(player => {\n player.fadeOut = fadeOut;\n });\n }\n /**\n * The state of the players object. Returns "started" if any of the players are playing.\n */\n get state() {\n const playing = Array.from(this._players).some(([_, player]) => player.state === "started");\n return playing ? "started" : "stopped";\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name);\n }\n /**\n * Get a player by name.\n * @param name The players name as defined in the constructor object or `add` method.\n */\n player(name) {\n assert(this.has(name), `No Player with the name ${name} exists on this object`);\n if (!this._players.has(name)) {\n const player = new Player({\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n url: this._buffers.get(name),\n }).connect(this.output);\n this._players.set(name, player);\n }\n return this._players.get(name);\n }\n /**\n * If all the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Add a player by name and url to the Players\n * @param name A unique name to give the player\n * @param url Either the url of the bufer or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(name, url, callback) {\n assert(!this._buffers.has(name), "A buffer with that name already exists on this object");\n this._buffers.add(name, url, callback);\n return this;\n }\n /**\n * Stop all of the players at the given time\n * @param time The time to stop all of the players.\n */\n stopAll(time) {\n this._players.forEach(player => player.stop(time));\n return this;\n }\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.volume.dispose();\n this._players.forEach(player => player.dispose());\n this._buffers.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Players.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/GrainPlayer.js\n\n\n\n\n\n\n\n\n/**\n * GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis).\n * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the\n * amount of time each small chunk of audio is played for and the overlap is the\n * amount of crossfading transition time between successive grains.\n * @category Source\n */\nclass GrainPlayer extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]));\n this.name = "GrainPlayer";\n /**\n * Internal loopStart value\n */\n this._loopStart = 0;\n /**\n * Internal loopStart value\n */\n this._loopEnd = 0;\n /**\n * All of the currently playing BufferSources\n */\n this._activeSources = [];\n const options = optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]);\n this.buffer = new ToneAudioBuffer({\n onload: options.onload,\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this._clock = new Clock({\n context: this.context,\n callback: this._tick.bind(this),\n frequency: 1 / options.grainSize\n });\n this._playbackRate = options.playbackRate;\n this._grainSize = options.grainSize;\n this._overlap = options.overlap;\n this.detune = options.detune;\n // setup\n this.overlap = options.overlap;\n this.loop = options.loop;\n this.playbackRate = options.playbackRate;\n this.grainSize = options.grainSize;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.reverse = options.reverse;\n this._clock.on("stop", this._onstop.bind(this));\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n onload: noOp,\n onerror: noOp,\n overlap: 0.1,\n grainSize: 0.2,\n playbackRate: 1,\n detune: 0,\n loop: false,\n loopStart: 0,\n loopEnd: 0,\n reverse: false\n });\n }\n /**\n * Internal start method\n */\n _start(time, offset, duration) {\n offset = defaultArg(offset, 0);\n offset = this.toSeconds(offset);\n time = this.toSeconds(time);\n const grainSize = 1 / this._clock.frequency.getValueAtTime(time);\n this._clock.start(time, offset / grainSize);\n if (duration) {\n this.stop(time + this.toSeconds(duration));\n }\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Internal stop method\n */\n _stop(time) {\n this._clock.stop(time);\n }\n /**\n * Invoked when the clock is stopped\n */\n _onstop(time) {\n // stop the players\n this._activeSources.forEach((source) => {\n source.fadeOut = 0;\n source.stop(time);\n });\n this.onstop(this);\n }\n /**\n * Invoked on each clock tick. scheduled a new grain at this time.\n */\n _tick(time) {\n // check if it should stop looping\n const ticks = this._clock.getTicksAtTime(time);\n const offset = ticks * this._grainSize;\n this.log("offset", offset);\n if (!this.loop && offset > this.buffer.duration) {\n this.stop(time);\n return;\n }\n // at the beginning of the file, the fade in should be 0\n const fadeIn = offset < this._overlap ? 0 : this._overlap;\n // create a buffer source\n const source = new ToneBufferSource({\n context: this.context,\n url: this.buffer,\n fadeIn: fadeIn,\n fadeOut: this._overlap,\n loop: this.loop,\n loopStart: this._loopStart,\n loopEnd: this._loopEnd,\n // compute the playbackRate based on the detune\n playbackRate: intervalToFrequencyRatio(this.detune / 100)\n }).connect(this.output);\n source.start(time, this._grainSize * ticks);\n source.stop(time + this._grainSize / this.playbackRate);\n // add it to the active sources\n this._activeSources.push(source);\n // remove it when it\'s done\n source.onended = () => {\n const index = this._activeSources.indexOf(source);\n if (index !== -1) {\n this._activeSources.splice(index, 1);\n }\n };\n }\n /**\n * The playback rate of the sample\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n assertRange(rate, 0.001);\n this._playbackRate = rate;\n this.grainSize = this._grainSize;\n }\n /**\n * The loop start time.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopStart = this.toSeconds(time);\n }\n /**\n * The loop end time.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopEnd = this.toSeconds(time);\n }\n /**\n * The direction the buffer should play in\n */\n get reverse() {\n return this.buffer.reverse;\n }\n set reverse(rev) {\n this.buffer.reverse = rev;\n }\n /**\n * The size of each chunk of audio that the\n * buffer is chopped into and played back at.\n */\n get grainSize() {\n return this._grainSize;\n }\n set grainSize(size) {\n this._grainSize = this.toSeconds(size);\n this._clock.frequency.setValueAtTime(this._playbackRate / this._grainSize, this.now());\n }\n /**\n * The duration of the cross-fade between successive grains.\n */\n get overlap() {\n return this._overlap;\n }\n set overlap(time) {\n const computedTime = this.toSeconds(time);\n assertRange(computedTime, 0);\n this._overlap = computedTime;\n }\n /**\n * If all the buffer is loaded\n */\n get loaded() {\n return this.buffer.loaded;\n }\n dispose() {\n super.dispose();\n this.buffer.dispose();\n this._clock.dispose();\n this._activeSources.forEach((source) => source.dispose());\n return this;\n }\n}\n//# sourceMappingURL=GrainPlayer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Abs.js\n\n\n/**\n * Return the absolute value of an incoming signal.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst abs = new Tone.Abs().toDestination();\n * \tconst signal = new Tone.Signal(1);\n * \tsignal.rampTo(-1, 0.5);\n * \tsignal.connect(abs);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Abs_Abs extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Abs";\n /**\n * The node which converts the audio ranges\n */\n this._abs = new WaveShaper({\n context: this.context,\n mapping: val => {\n if (Math.abs(val) < 0.001) {\n return 0;\n }\n else {\n return Math.abs(val);\n }\n },\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._abs;\n /**\n * The output range [0, 1]\n */\n this.output = this._abs;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._abs.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Abs.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GainToAudio.js\n\n\n/**\n * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1].\n * See [[AudioToGain]].\n * @category Signal\n */\nclass GainToAudio_GainToAudio extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "GainToAudio";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper({\n context: this.context,\n mapping: x => Math.abs(x) * 2 - 1,\n });\n /**\n * The NormalRange input [0, 1]\n */\n this.input = this._norm;\n /**\n * The AudioRange output [-1, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GainToAudio.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Negate.js\n\n\n/**\n * Negate the incoming signal. i.e. an input signal of 10 will output -10\n *\n * @example\n * const neg = new Tone.Negate();\n * const sig = new Tone.Signal(-2).connect(neg);\n * // output of neg is positive 2.\n * @category Signal\n */\nclass Negate_Negate extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Negate";\n /**\n * negation is done by multiplying by -1\n */\n this._multiply = new Multiply({\n context: this.context,\n value: -1,\n });\n /**\n * The input and output are equal to the multiply node\n */\n this.input = this._multiply;\n this.output = this._multiply;\n }\n /**\n * clean up\n * @returns {Negate} this\n */\n dispose() {\n super.dispose();\n this._multiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Negate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Subtract.js\n\n\n\n\n\n/**\n * Subtract the signal connected to the input is subtracted from the signal connected\n * The subtrahend.\n *\n * @example\n * // subtract a scalar from a signal\n * const sub = new Tone.Subtract(1);\n * const sig = new Tone.Signal(4).connect(sub);\n * // the output of sub is 3.\n * @example\n * // subtract two signals\n * const sub = new Tone.Subtract();\n * const sigA = new Tone.Signal(10);\n * const sigB = new Tone.Signal(2.5);\n * sigA.connect(sub);\n * sigB.connect(sub.subtrahend);\n * // output of sub is 7.5\n * @category Signal\n */\nclass Subtract_Subtract extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Subtract_Subtract.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Subtract";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * Negate the input of the second input before connecting it to the summing node.\n */\n this._neg = new Negate({ context: this.context });\n /**\n * The value which is subtracted from the main signal\n */\n this.subtrahend = this._param;\n connectSeries(this._constantSource, this._neg, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._neg.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Subtract.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThanZero.js\n\n\n\n\n/**\n * GreaterThanZero outputs 1 when the input is strictly greater than zero\n * @example\n * return Tone.Offline(() => {\n * \tconst gt0 = new Tone.GreaterThanZero().toDestination();\n * \tconst sig = new Tone.Signal(0.5).connect(gt0);\n * \tsig.setValueAtTime(-1, 0.05);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThanZero_GreaterThanZero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThanZero_GreaterThanZero.getDefaults(), arguments)));\n this.name = "GreaterThanZero";\n this._thresh = this.output = new WaveShaper({\n context: this.context,\n length: 127,\n mapping: (val) => {\n if (val <= 0) {\n return 0;\n }\n else {\n return 1;\n }\n },\n });\n this._scale = this.input = new Multiply({\n context: this.context,\n value: 10000\n });\n // connections\n this._scale.connect(this._thresh);\n }\n dispose() {\n super.dispose();\n this._scale.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThanZero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThan.js\n\n\n\n\n\n/**\n * Output 1 if the signal is greater than the value, otherwise outputs 0.\n * can compare two signals or a signal and a number.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst gt = new Tone.GreaterThan(2).toDestination();\n * \tconst sig = new Tone.Signal(4).connect(gt);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThan_GreaterThan extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"])));\n this.name = "GreaterThan";\n this.override = false;\n const options = optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"]);\n this._subtract = this.input = new Subtract({\n context: this.context,\n value: options.value\n });\n this._gtz = this.output = new GreaterThanZero({ context: this.context });\n this.comparator = this._param = this._subtract.subtrahend;\n readOnly(this, "comparator");\n // connect\n this._subtract.connect(this._gtz);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._gtz.dispose();\n this._subtract.dispose();\n this.comparator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThan.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Pow.js\n\n\n\n/**\n * Pow applies an exponent to the incoming signal. The incoming signal must be AudioRange [-1, 1]\n *\n * @example\n * const pow = new Tone.Pow(2);\n * const sig = new Tone.Signal(0.5).connect(pow);\n * // output of pow is 0.25.\n * @category Signal\n */\nclass Pow_Pow extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"])));\n this.name = "Pow";\n const options = optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"]);\n this._exponentScaler = this.input = this.output = new WaveShaper({\n context: this.context,\n mapping: this._expFunc(options.value),\n length: 8192,\n });\n this._exponent = options.value;\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n value: 1,\n });\n }\n /**\n * the function which maps the waveshaper\n * @param exponent exponent value\n */\n _expFunc(exponent) {\n return (val) => {\n return Math.pow(Math.abs(val), exponent);\n };\n }\n /**\n * The value of the exponent.\n */\n get value() {\n return this._exponent;\n }\n set value(exponent) {\n this._exponent = exponent;\n this._exponentScaler.setMap(this._expFunc(this._exponent));\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._exponentScaler.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Pow.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ScaleExp.js\n\n\n\n/**\n * Performs an exponential scaling on an input signal.\n * Scales a NormalRange value [0,1] exponentially\n * to the output range of outputMin to outputMax.\n * @example\n * const scaleExp = new Tone.ScaleExp(0, 100, 2);\n * const signal = new Tone.Signal(0.5).connect(scaleExp);\n * @category Signal\n */\nclass ScaleExp_ScaleExp extends (/* unused pure expression or super */ null && (Scale)) {\n constructor() {\n super(Object.assign(optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"])));\n this.name = "ScaleExp";\n const options = optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"]);\n this.input = this._exp = new Pow({\n context: this.context,\n value: options.exponent,\n });\n this._exp.connect(this._mult);\n }\n static getDefaults() {\n return Object.assign(Scale.getDefaults(), {\n exponent: 1,\n });\n }\n /**\n * Instead of interpolating linearly between the [[min]] and\n * [[max]] values, setting the exponent will interpolate between\n * the two values with an exponential curve.\n */\n get exponent() {\n return this._exp.value;\n }\n set exponent(exp) {\n this._exp.value = exp;\n }\n dispose() {\n super.dispose();\n this._exp.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ScaleExp.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SyncedSignal.js\n\n\n\n\n/**\n * Adds the ability to synchronize the signal to the [[Transport]]\n */\nclass SyncedSignal extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "SyncedSignal";\n /**\n * Don\'t override when something is connected to the input\n */\n this.override = false;\n const options = optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]);\n this._lastVal = options.value;\n this._synced = this.context.transport.scheduleRepeat(this._onTick.bind(this), "1i");\n this._syncedCallback = this._anchorValue.bind(this);\n this.context.transport.on("start", this._syncedCallback);\n this.context.transport.on("pause", this._syncedCallback);\n this.context.transport.on("stop", this._syncedCallback);\n // disconnect the constant source from the output and replace it with another one\n this._constantSource.disconnect();\n this._constantSource.stop(0);\n // create a new one\n this._constantSource = this.output = new ToneConstantSource({\n context: this.context,\n offset: options.value,\n units: options.units,\n }).start(0);\n this.setValueAtTime(options.value, 0);\n }\n /**\n * Callback which is invoked every tick.\n */\n _onTick(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n // approximate ramp curves with linear ramps\n if (this._lastVal !== val) {\n this._lastVal = val;\n this._constantSource.offset.setValueAtTime(val, time);\n }\n }\n /**\n * Anchor the value at the start and stop of the Transport\n */\n _anchorValue(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n this._lastVal = val;\n this._constantSource.offset.cancelAndHoldAtTime(time);\n this._constantSource.offset.setValueAtTime(val, time);\n }\n getValueAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n return super.getValueAtTime(computedTime);\n }\n setValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setValueAtTime(value, computedTime);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.linearRampToValueAtTime(value, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.exponentialRampToValueAtTime(value, computedTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.setTargetAtTime(value, computedTime, timeConstant);\n return this;\n }\n cancelScheduledValues(startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.cancelScheduledValues(computedTime);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n duration = this.toSeconds(duration);\n super.setValueCurveAtTime(values, computedTime, duration, scaling);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.cancelAndHoldAtTime(computedTime);\n return this;\n }\n setRampPoint(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setRampPoint(computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.exponentialRampTo(value, rampTime, computedTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.linearRampTo(value, rampTime, computedTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.targetRampTo(value, rampTime, computedTime);\n return this;\n }\n dispose() {\n super.dispose();\n this.context.transport.clear(this._synced);\n this.context.transport.off("start", this._syncedCallback);\n this.context.transport.off("pause", this._syncedCallback);\n this.context.transport.off("stop", this._syncedCallback);\n this._constantSource.dispose();\n return this;\n }\n}\n//# sourceMappingURL=SyncedSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/Envelope.js\n\n\n\n\n\n\n\n\n/**\n * Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)\n * envelope generator. Envelope outputs a signal which\n * can be connected to an AudioParam or Tone.Signal.\n * ```\n * /\\\n * / \\\n * / \\\n * / \\\n * / \\___________\n * / \\\n * / \\\n * / \\\n * / \\\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 0.5,\n * \t\trelease: 0.8,\n * \t}).toDestination();\n * \tenv.triggerAttackRelease(0.5);\n * }, 1.5, 1);\n * @category Component\n */\nclass Envelope_Envelope extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "Envelope";\n /**\n * the signal which is output.\n */\n this._sig = new Signal_Signal({\n context: this.context,\n value: 0,\n });\n /**\n * The output signal of the envelope\n */\n this.output = this._sig;\n /**\n * Envelope has no input\n */\n this.input = undefined;\n const options = Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this.attack = options.attack;\n this.decay = options.decay;\n this.sustain = options.sustain;\n this.release = options.release;\n this.attackCurve = options.attackCurve;\n this.releaseCurve = options.releaseCurve;\n this.decayCurve = options.decayCurve;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.01,\n attackCurve: "linear",\n decay: 0.1,\n decayCurve: "exponential",\n release: 1,\n releaseCurve: "exponential",\n sustain: 0.5,\n });\n }\n /**\n * Read the current value of the envelope. Useful for\n * synchronizing visual output to the envelope.\n */\n get value() {\n return this.getValueAtTime(this.now());\n }\n /**\n * Get the curve\n * @param curve\n * @param direction In/Out\n * @return The curve name\n */\n _getCurve(curve, direction) {\n if (TypeCheck_isString(curve)) {\n return curve;\n }\n else {\n // look up the name in the curves array\n let curveName;\n for (curveName in EnvelopeCurves) {\n if (EnvelopeCurves[curveName][direction] === curve) {\n return curveName;\n }\n }\n // return the custom curve\n return curve;\n }\n }\n /**\n * Assign a the curve to the given name using the direction\n * @param name\n * @param direction In/Out\n * @param curve\n */\n _setCurve(name, direction, curve) {\n // check if it\'s a valid type\n if (TypeCheck_isString(curve) && Reflect.has(EnvelopeCurves, curve)) {\n const curveDef = EnvelopeCurves[curve];\n if (TypeCheck_isObject(curveDef)) {\n if (name !== "_decayCurve") {\n this[name] = curveDef[direction];\n }\n }\n else {\n this[name] = curveDef;\n }\n }\n else if (TypeCheck_isArray(curve) && name !== "_decayCurve") {\n this[name] = curve;\n }\n else {\n throw new Error("Envelope: invalid curve: " + curve);\n }\n }\n /**\n * The shape of the attack.\n * Can be any of these strings:\n * * "linear"\n * * "exponential"\n * * "sine"\n * * "cosine"\n * * "bounce"\n * * "ripple"\n * * "step"\n *\n * Can also be an array which describes the curve. Values\n * in the array are evenly subdivided and linearly\n * interpolated over the duration of the attack.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope(0.4).toDestination();\n * \tenv.attackCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get attackCurve() {\n return this._getCurve(this._attackCurve, "In");\n }\n set attackCurve(curve) {\n this._setCurve("_attackCurve", "In", curve);\n }\n /**\n * The shape of the release. See the attack curve types.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \tenv.triggerAttack();\n * \t// release curve could also be defined by an array\n * \tenv.releaseCurve = [1, 0.3, 0.4, 0.2, 0.7, 0];\n * \tenv.triggerRelease(0.2);\n * }, 1, 1);\n */\n get releaseCurve() {\n return this._getCurve(this._releaseCurve, "Out");\n }\n set releaseCurve(curve) {\n this._setCurve("_releaseCurve", "Out", curve);\n }\n /**\n * The shape of the decay either "linear" or "exponential"\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tsustain: 0.1,\n * \t\tdecay: 0.5\n * \t}).toDestination();\n * \tenv.decayCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get decayCurve() {\n return this._decayCurve;\n }\n set decayCurve(curve) {\n Debug_assert(["linear", "exponential"].some(c => c === curve), `Invalid envelope curve: ${curve}`);\n this._decayCurve = curve;\n }\n /**\n * Trigger the attack/decay portion of the ADSR envelope.\n * @param time When the attack should start.\n * @param velocity The velocity of the envelope scales the vales.\n * number between 0-1\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the attack 0.5 seconds from now with a velocity of 0.2\n * env.triggerAttack("+0.5", 0.2);\n */\n triggerAttack(time, velocity = 1) {\n this.log("triggerAttack", time, velocity);\n time = this.toSeconds(time);\n const originalAttack = this.toSeconds(this.attack);\n let attack = originalAttack;\n const decay = this.toSeconds(this.decay);\n // check if it\'s not a complete attack\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n // subtract the current value from the attack time\n const attackRate = 1 / attack;\n const remainingDistance = 1 - currentValue;\n // the attack is now the remaining time\n attack = remainingDistance / attackRate;\n }\n // attack\n if (attack < this.sampleTime) {\n this._sig.cancelScheduledValues(time);\n // case where the attack time is 0 should set instantly\n this._sig.setValueAtTime(velocity, time);\n }\n else if (this._attackCurve === "linear") {\n this._sig.linearRampTo(velocity, attack, time);\n }\n else if (this._attackCurve === "exponential") {\n this._sig.targetRampTo(velocity, attack, time);\n }\n else {\n this._sig.cancelAndHoldAtTime(time);\n let curve = this._attackCurve;\n // find the starting position in the curve\n for (let i = 1; i < curve.length; i++) {\n // the starting index is between the two values\n if (curve[i - 1] <= currentValue && currentValue <= curve[i]) {\n curve = this._attackCurve.slice(i);\n // the first index is the current value\n curve[0] = currentValue;\n break;\n }\n }\n this._sig.setValueCurveAtTime(curve, time, attack, velocity);\n }\n // decay\n if (decay && this.sustain < 1) {\n const decayValue = velocity * this.sustain;\n const decayStart = time + attack;\n this.log("decay", decayStart);\n if (this._decayCurve === "linear") {\n this._sig.linearRampToValueAtTime(decayValue, decay + decayStart);\n }\n else {\n this._sig.exponentialApproachValueAtTime(decayValue, decayStart, decay);\n }\n }\n return this;\n }\n /**\n * Triggers the release of the envelope.\n * @param time When the release portion of the envelope should start.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator({\n * \ttype: "sawtooth"\n * }).connect(env).start();\n * env.triggerAttack();\n * // trigger the release half a second after the attack\n * env.triggerRelease("+0.5");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n time = this.toSeconds(time);\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n const release = this.toSeconds(this.release);\n if (release < this.sampleTime) {\n this._sig.setValueAtTime(0, time);\n }\n else if (this._releaseCurve === "linear") {\n this._sig.linearRampTo(0, release, time);\n }\n else if (this._releaseCurve === "exponential") {\n this._sig.targetRampTo(0, release, time);\n }\n else {\n Debug_assert(TypeCheck_isArray(this._releaseCurve), "releaseCurve must be either \'linear\', \'exponential\' or an array");\n this._sig.cancelAndHoldAtTime(time);\n this._sig.setValueCurveAtTime(this._releaseCurve, time, release, currentValue);\n }\n }\n return this;\n }\n /**\n * Get the scheduled value at the given time. This will\n * return the unconverted (raw) value.\n * @example\n * const env = new Tone.Envelope(0.5, 1, 0.4, 2);\n * env.triggerAttackRelease(2);\n * setInterval(() => console.log(env.getValueAtTime(Tone.now())), 100);\n */\n getValueAtTime(time) {\n return this._sig.getValueAtTime(time);\n }\n /**\n * triggerAttackRelease is shorthand for triggerAttack, then waiting\n * some duration, then triggerRelease.\n * @param duration The duration of the sustain.\n * @param time When the attack should be triggered.\n * @param velocity The velocity of the envelope.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the release 0.5 seconds after the attack\n * env.triggerAttackRelease(0.5);\n */\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + this.toSeconds(duration));\n return this;\n }\n /**\n * Cancels all scheduled envelope changes after the given time.\n */\n cancel(after) {\n this._sig.cancelScheduledValues(this.toSeconds(after));\n return this;\n }\n /**\n * Connect the envelope to a destination node.\n */\n connect(destination, outputNumber = 0, inputNumber = 0) {\n Signal_connectSignal(this, destination, outputNumber, inputNumber);\n return this;\n }\n /**\n * Render the envelope curve to an array of the given length.\n * Good for visualizing the envelope curve. Rescales the duration of the\n * envelope to fit the length.\n */\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / this.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, this.context.sampleRate);\n // normalize the ADSR for the given duration with 20% sustain time\n const attackPortion = this.toSeconds(this.attack) + this.toSeconds(this.decay);\n const envelopeDuration = attackPortion + this.toSeconds(this.release);\n const sustainTime = envelopeDuration * 0.1;\n const totalDuration = envelopeDuration + sustainTime;\n // @ts-ignore\n const clone = new this.constructor(Object.assign(this.get(), {\n attack: duration * this.toSeconds(this.attack) / totalDuration,\n decay: duration * this.toSeconds(this.decay) / totalDuration,\n release: duration * this.toSeconds(this.release) / totalDuration,\n context\n }));\n clone._sig.toDestination();\n clone.triggerAttackRelease(duration * (attackPortion + sustainTime) / totalDuration, 0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n }\n dispose() {\n super.dispose();\n this._sig.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "decay", void 0);\n__decorate([\n range(0, 1)\n], Envelope_Envelope.prototype, "sustain", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "release", void 0);\n/**\n * Generate some complex envelope curves.\n */\nconst EnvelopeCurves = (() => {\n const curveLen = 128;\n let i;\n let k;\n // cosine curve\n const cosineCurve = [];\n for (i = 0; i < curveLen; i++) {\n cosineCurve[i] = Math.sin((i / (curveLen - 1)) * (Math.PI / 2));\n }\n // ripple curve\n const rippleCurve = [];\n const rippleCurveFreq = 6.4;\n for (i = 0; i < curveLen - 1; i++) {\n k = (i / (curveLen - 1));\n const sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1;\n rippleCurve[i] = sineWave / 10 + k * 0.83;\n }\n rippleCurve[curveLen - 1] = 1;\n // stairs curve\n const stairsCurve = [];\n const steps = 5;\n for (i = 0; i < curveLen; i++) {\n stairsCurve[i] = Math.ceil((i / (curveLen - 1)) * steps) / steps;\n }\n // in-out easing curve\n const sineCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k));\n }\n // a bounce curve\n const bounceCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n const freq = Math.pow(k, 3) * 4 + 0.2;\n const val = Math.cos(freq * Math.PI * 2 * k);\n bounceCurve[i] = Math.abs(val * (1 - k));\n }\n /**\n * Invert a value curve to make it work for the release\n */\n function invertCurve(curve) {\n const out = new Array(curve.length);\n for (let j = 0; j < curve.length; j++) {\n out[j] = 1 - curve[j];\n }\n return out;\n }\n /**\n * reverse the curve\n */\n function reverseCurve(curve) {\n return curve.slice(0).reverse();\n }\n /**\n * attack and release curve arrays\n */\n return {\n bounce: {\n In: invertCurve(bounceCurve),\n Out: bounceCurve,\n },\n cosine: {\n In: cosineCurve,\n Out: reverseCurve(cosineCurve),\n },\n exponential: "exponential",\n linear: "linear",\n ripple: {\n In: rippleCurve,\n Out: invertCurve(rippleCurve),\n },\n sine: {\n In: sineCurve,\n Out: invertCurve(sineCurve),\n },\n step: {\n In: stairsCurve,\n Out: invertCurve(stairsCurve),\n },\n };\n})();\n//# sourceMappingURL=Envelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Instrument.js\n\n\n\n\n/**\n * Base-class for all instruments\n */\nclass Instrument_Instrument extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments));\n /**\n * Keep track of all events scheduled to the transport\n * when the instrument is \'synced\'\n */\n this._scheduledEvents = [];\n /**\n * If the instrument is currently synced\n */\n this._synced = false;\n this._original_triggerAttack = this.triggerAttack;\n this._original_triggerRelease = this.triggerRelease;\n const options = Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments);\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n volume: 0,\n });\n }\n /**\n * Sync the instrument to the Transport. All subsequent calls of\n * [[triggerAttack]] and [[triggerRelease]] will be scheduled along the transport.\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.volume.value = -6;\n * fmSynth.sync();\n * // schedule 3 notes when the transport first starts\n * fmSynth.triggerAttackRelease("C4", "8n", 0);\n * fmSynth.triggerAttackRelease("E4", "8n", "8n");\n * fmSynth.triggerAttackRelease("G4", "8n", "4n");\n * // start the transport to hear the notes\n * Tone.Transport.start();\n */\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n /**\n * set _sync\n */\n _syncState() {\n let changed = false;\n if (!this._synced) {\n this._synced = true;\n changed = true;\n }\n return changed;\n }\n /**\n * Wrap the given method so that it can be synchronized\n * @param method Which method to wrap and sync\n * @param timePosition What position the time argument appears in\n */\n _syncMethod(method, timePosition) {\n const originalMethod = this["_original_" + method] = this[method];\n this[method] = (...args) => {\n const time = args[timePosition];\n const id = this.context.transport.schedule((t) => {\n args[timePosition] = t;\n originalMethod.apply(this, args);\n }, time);\n this._scheduledEvents.push(id);\n };\n }\n /**\n * Unsync the instrument from the Transport\n */\n unsync() {\n this._scheduledEvents.forEach(id => this.context.transport.clear(id));\n this._scheduledEvents = [];\n if (this._synced) {\n this._synced = false;\n this.triggerAttack = this._original_triggerAttack;\n this.triggerRelease = this._original_triggerRelease;\n }\n return this;\n }\n /**\n * Trigger the attack and then the release after the duration.\n * @param note The note to trigger.\n * @param duration How long the note should be held for before\n * triggering the release. This value must be greater than 0.\n * @param time When the note should be triggered.\n * @param velocity The velocity the note should be triggered at.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger "C4" for the duration of an 8th note\n * synth.triggerAttackRelease("C4", "8n");\n */\n triggerAttackRelease(note, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n const computedDuration = this.toSeconds(duration);\n this.triggerAttack(note, computedTime, velocity);\n this.triggerRelease(computedTime + computedDuration);\n return this;\n }\n /**\n * clean up\n * @returns {Instrument} this\n */\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.unsync();\n this._scheduledEvents = [];\n return this;\n }\n}\n//# sourceMappingURL=Instrument.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Monophonic.js\n\n\n\n\n\n\n/**\n * Abstract base class for other monophonic instruments to extend.\n */\nclass Monophonic_Monophonic extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments));\n const options = Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments);\n this.portamento = options.portamento;\n this.onsilence = options.onsilence;\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n detune: 0,\n onsilence: Interface_noOp,\n portamento: 0,\n });\n }\n /**\n * Trigger the attack of the note optionally with a given velocity.\n * @param note The note to trigger.\n * @param time When the note should start.\n * @param velocity The velocity scaler determines how "loud" the note will be triggered.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger the note a half second from now at half velocity\n * synth.triggerAttack("C4", "+0.5", 0.5);\n */\n triggerAttack(note, time, velocity = 1) {\n this.log("triggerAttack", note, time, velocity);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeAttack(seconds, velocity);\n this.setNote(note, seconds);\n return this;\n }\n /**\n * Trigger the release portion of the envelope\n * @param time If no time is given, the release happens immediatly\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // trigger the release a second from now\n * synth.triggerRelease("+1");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeRelease(seconds);\n return this;\n }\n /**\n * Set the note at the given time. If no time is given, the note\n * will set immediately.\n * @param note The note to change to.\n * @param time The time when the note should be set.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // change to F#6 in one quarter note from now.\n * synth.setNote("F#6", "+4n");\n */\n setNote(note, time) {\n const computedTime = this.toSeconds(time);\n const computedFrequency = note instanceof Frequency_FrequencyClass ? note.toFrequency() : note;\n if (this.portamento > 0 && this.getLevelAtTime(computedTime) > 0.05) {\n const portTime = this.toSeconds(this.portamento);\n this.frequency.exponentialRampTo(computedFrequency, portTime, computedTime);\n }\n else {\n this.frequency.setValueAtTime(computedFrequency, computedTime);\n }\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Monophonic_Monophonic.prototype, "portamento", void 0);\n//# sourceMappingURL=Monophonic.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/AmplitudeEnvelope.js\n\n\n\n/**\n * AmplitudeEnvelope is a Tone.Envelope connected to a gain node.\n * Unlike Tone.Envelope, which outputs the envelope\'s value, AmplitudeEnvelope accepts\n * an audio signal as the input and will apply the envelope to the amplitude\n * of the signal.\n * Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst ampEnv = new Tone.AmplitudeEnvelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 1.0,\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \t// create an oscillator and connect it\n * \tconst osc = new Tone.Oscillator().connect(ampEnv).start();\n * \t// trigger the envelopes attack and release "8t" apart\n * \tampEnv.triggerAttackRelease("8t");\n * }, 1.5, 1);\n * @category Component\n */\nclass AmplitudeEnvelope_AmplitudeEnvelope extends Envelope_Envelope {\n constructor() {\n super(Defaults_optionsFromArguments(AmplitudeEnvelope_AmplitudeEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "AmplitudeEnvelope";\n this._gainNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n this.output = this._gainNode;\n this.input = this._gainNode;\n this._sig.connect(this._gainNode.gain);\n this.output = this._gainNode;\n this.input = this._gainNode;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._gainNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AmplitudeEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Synth.js\n\n\n\n\n\n\n\n\n/**\n * Synth is composed simply of a [[OmniOscillator]] routed through an [[AmplitudeEnvelope]].\n * ```\n * +----------------+ +-------------------+\n * | OmniOscillator +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +----------------+ +-------------------+\n * ```\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass Synth_Synth extends Monophonic_Monophonic {\n constructor() {\n super(Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments));\n this.name = "Synth";\n const options = Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator_OmniOscillator(Object.assign({\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }, options.oscillator));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.envelope = new AmplitudeEnvelope_AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the oscillators to the output\n this.oscillator.chain(this.envelope, this.output);\n Interface_readOnly(this, ["oscillator", "frequency", "detune", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic_Monophonic.getDefaults(), {\n envelope: Object.assign(Defaults_omitFromObject(Envelope_Envelope.getDefaults(), Object.keys(ToneAudioNode_ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.3,\n }),\n oscillator: Object.assign(Defaults_omitFromObject(OmniOscillator_OmniOscillator.getDefaults(), [...Object.keys(Source_Source.getDefaults()), "frequency", "detune"]), {\n type: "triangle",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity) {\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n this.oscillator.start(time);\n // if there is no release portion, stop the oscillator\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Synth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/ModulationSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for both AM and FM synths\n */\nclass ModulationSynth_ModulationSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments));\n this.name = "ModulationSynth";\n const options = optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments);\n this._carrier = new Synth({\n context: this.context,\n oscillator: options.oscillator,\n envelope: options.envelope,\n onsilence: () => this.onsilence(this),\n volume: -10,\n });\n this._modulator = new Synth({\n context: this.context,\n oscillator: options.modulation,\n envelope: options.modulationEnvelope,\n volume: -10,\n });\n this.oscillator = this._carrier.oscillator;\n this.envelope = this._carrier.envelope;\n this.modulation = this._modulator.oscillator;\n this.modulationEnvelope = this._modulator.envelope;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this.detune = new Signal({\n context: this.context,\n value: options.detune,\n units: "cents"\n });\n this.harmonicity = new Multiply({\n context: this.context,\n value: options.harmonicity,\n minValue: 0,\n });\n this._modulationNode = new Gain({\n context: this.context,\n gain: 0,\n });\n readOnly(this, ["frequency", "harmonicity", "oscillator", "envelope", "modulation", "modulationEnvelope", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n harmonicity: 3,\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "sine"\n }),\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.01,\n decay: 0.01,\n sustain: 1,\n release: 0.5\n }),\n modulation: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "square"\n }),\n modulationEnvelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.5,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n })\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this._carrier._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this._modulator._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this._carrier._triggerEnvelopeRelease(time);\n // @ts-ignore\n this._modulator._triggerEnvelopeRelease(time);\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._modulationNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ModulationSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/AMSynth.js\n\n\n\n/**\n * AMSynth uses the output of one Tone.Synth to modulate the\n * amplitude of another Tone.Synth. The harmonicity (the ratio between\n * the two signals) affects the timbre of the output signal greatly.\n * Read more about Amplitude Modulation Synthesis on\n * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm).\n *\n * @example\n * const synth = new Tone.AMSynth().toDestination();\n * synth.triggerAttackRelease("C4", "4n");\n *\n * @category Instrument\n */\nclass AMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(AMSynth.getDefaults(), arguments));\n this.name = "AMSynth";\n this._modulationScale = new AudioToGain({\n context: this.context,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n }\n dispose() {\n super.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/BiquadFilter.js\n\n\n\n\n/**\n * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode).\n * BiquadFilter is similar to [[Filter]] but doesn\'t have the option to set the "rolloff" value.\n * @category Component\n */\nclass BiquadFilter_BiquadFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "BiquadFilter";\n const options = optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._filter = this.context.createBiquadFilter();\n this.input = this.output = this._filter;\n this.Q = new Param({\n context: this.context,\n units: "number",\n value: options.Q,\n param: this._filter.Q,\n });\n this.frequency = new Param({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n param: this._filter.frequency,\n });\n this.detune = new Param({\n context: this.context,\n units: "cents",\n value: options.detune,\n param: this._filter.detune,\n });\n this.gain = new Param({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n param: this._filter.gain,\n });\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n type: "lowpass",\n frequency: 350,\n detune: 0,\n gain: 0,\n });\n }\n /**\n * The type of this BiquadFilterNode. For a complete list of types and their attributes, see the\n * [Web Audio API](https://webaudio.github.io/web-audio-api/#dom-biquadfiltertype-lowpass)\n */\n get type() {\n return this._filter.type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._filter.type = type;\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n // start with all 1s\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n // clone the filter to remove any connections which may be changing the value\n const filterClone = this.context.createBiquadFilter();\n filterClone.type = this.type;\n filterClone.Q.value = this.Q.value;\n filterClone.frequency.value = this.frequency.value;\n filterClone.gain.value = this.gain.value;\n filterClone.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this._filter.disconnect();\n this.Q.dispose();\n this.frequency.dispose();\n this.gain.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BiquadFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Filter.js\n\n\n\n\n\n\n\n\n/**\n * Tone.Filter is a filter which allows for all of the same native methods\n * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).\n * Tone.Filter has the added ability to set the filter rolloff at -12\n * (default), -24 and -48.\n * @example\n * const filter = new Tone.Filter(1500, "highpass").toDestination();\n * filter.frequency.rampTo(20000, 10);\n * const noise = new Tone.Noise().connect(filter).start();\n * @category Component\n */\nclass Filter_Filter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]));\n this.name = "Filter";\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._filters = [];\n const options = optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]);\n this._filters = [];\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.gain = new Signal({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n });\n this._type = options.type;\n this.rolloff = options.rolloff;\n readOnly(this, ["detune", "frequency", "gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n detune: 0,\n frequency: 350,\n gain: 0,\n rolloff: -12,\n type: "lowpass",\n });\n }\n /**\n * The type of the filter. Types: "lowpass", "highpass",\n * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._type = type;\n this._filters.forEach(filter => filter.type = type);\n }\n /**\n * The rolloff of the filter which is the drop in db\n * per octave. Implemented internally by cascading filters.\n * Only accepts the values -12, -24, -48 and -96.\n */\n get rolloff() {\n return this._rolloff;\n }\n set rolloff(rolloff) {\n const rolloffNum = isNumber(rolloff) ? rolloff : parseInt(rolloff, 10);\n const possibilities = [-12, -24, -48, -96];\n let cascadingCount = possibilities.indexOf(rolloffNum);\n // check the rolloff is valid\n assert(cascadingCount !== -1, `rolloff can only be ${possibilities.join(", ")}`);\n cascadingCount += 1;\n this._rolloff = rolloffNum;\n this.input.disconnect();\n this._filters.forEach(filter => filter.disconnect());\n this._filters = new Array(cascadingCount);\n for (let count = 0; count < cascadingCount; count++) {\n const filter = new BiquadFilter({\n context: this.context,\n });\n filter.type = this._type;\n this.frequency.connect(filter.frequency);\n this.detune.connect(filter.detune);\n this.Q.connect(filter.Q);\n this.gain.connect(filter.gain);\n this._filters[count] = filter;\n }\n this._internalChannels = this._filters;\n connectSeries(this.input, ...this._internalChannels, this.output);\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const filterClone = new BiquadFilter({\n frequency: this.frequency.value,\n gain: this.gain.value,\n Q: this.Q.value,\n type: this._type,\n detune: this.detune.value,\n });\n // start with all 1s\n const totalResponse = new Float32Array(len).map(() => 1);\n this._filters.forEach(() => {\n const response = filterClone.getFrequencyResponse(len);\n response.forEach((val, i) => totalResponse[i] *= val);\n });\n filterClone.dispose();\n return totalResponse;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._filters.forEach(filter => {\n filter.dispose();\n });\n writable(this, ["detune", "frequency", "gain", "Q"]);\n this.frequency.dispose();\n this.Q.dispose();\n this.detune.dispose();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Filter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/FrequencyEnvelope.js\n\n\n\n\n\n/**\n * FrequencyEnvelope is an [[Envelope]] which ramps between [[baseFrequency]]\n * and [[octaves]]. It can also have an optional [[exponent]] to adjust the curve\n * which it ramps.\n * @example\n * const oscillator = new Tone.Oscillator().toDestination().start();\n * const freqEnv = new Tone.FrequencyEnvelope({\n * \tattack: 0.2,\n * \tbaseFrequency: "C2",\n * \toctaves: 4\n * });\n * freqEnv.connect(oscillator.frequency);\n * freqEnv.triggerAttack();\n * @category Component\n */\nclass FrequencyEnvelope_FrequencyEnvelope extends (/* unused pure expression or super */ null && (Envelope)) {\n constructor() {\n super(optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "FrequencyEnvelope";\n const options = optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this._octaves = options.octaves;\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._exponent = this.input = new Pow({\n context: this.context,\n value: options.exponent\n });\n this._scale = this.output = new Scale({\n context: this.context,\n min: this._baseFrequency,\n max: this._baseFrequency * Math.pow(2, this._octaves),\n });\n this._sig.chain(this._exponent, this._scale);\n }\n static getDefaults() {\n return Object.assign(Envelope.getDefaults(), {\n baseFrequency: 200,\n exponent: 1,\n octaves: 4,\n });\n }\n /**\n * The envelope\'s minimum output value. This is the value which it\n * starts at.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(min) {\n const freq = this.toFrequency(min);\n assertRange(freq, 0);\n this._baseFrequency = freq;\n this._scale.min = this._baseFrequency;\n // update the max value when the min changes\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the baseFrequency that the\n * envelope will scale to.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._scale.max = this._baseFrequency * Math.pow(2, octaves);\n }\n /**\n * The envelope\'s exponent value.\n */\n get exponent() {\n return this._exponent.value;\n }\n set exponent(exponent) {\n this._exponent.value = exponent;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._exponent.dispose();\n this._scale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MonoSynth.js\n\n\n\n\n\n\n\n\n\n\n/**\n * MonoSynth is composed of one `oscillator`, one `filter`, and two `envelopes`.\n * The amplitude of the Oscillator and the cutoff frequency of the\n * Filter are controlled by Envelopes.\n * <img src="https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240">\n * @example\n * const synth = new Tone.MonoSynth({\n * \toscillator: {\n * \t\ttype: "square"\n * \t},\n * \tenvelope: {\n * \t\tattack: 0.1\n * \t}\n * }).toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass MonoSynth_MonoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments));\n this.name = "MonoSynth";\n const options = optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator(Object.assign(options.oscillator, {\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.filter = new Filter(Object.assign(options.filter, { context: this.context }));\n this.filterEnvelope = new FrequencyEnvelope(Object.assign(options.filterEnvelope, { context: this.context }));\n this.envelope = new AmplitudeEnvelope(Object.assign(options.envelope, { context: this.context }));\n // connect the oscillators to the output\n this.oscillator.chain(this.filter, this.envelope, this.output);\n // connect the filter envelope\n this.filterEnvelope.connect(this.filter.frequency);\n readOnly(this, ["oscillator", "frequency", "detune", "filter", "filterEnvelope", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.9,\n }),\n filter: Object.assign(omitFromObject(Filter.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n Q: 1,\n rolloff: -12,\n type: "lowpass",\n }),\n filterEnvelope: Object.assign(omitFromObject(FrequencyEnvelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.6,\n baseFrequency: 200,\n decay: 0.2,\n exponent: 2,\n octaves: 3,\n release: 2,\n sustain: 0.5,\n }),\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "sawtooth",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this.filterEnvelope.triggerAttack(time);\n this.oscillator.start(time);\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.filterEnvelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n this.filterEnvelope.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MonoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/DuoSynth.js\n\n\n\n\n\n\n\n\n/**\n * DuoSynth is a monophonic synth composed of two [[MonoSynths]] run in parallel with control over the\n * frequency ratio between the two voices and vibrato effect.\n * @example\n * const duoSynth = new Tone.DuoSynth().toDestination();\n * duoSynth.triggerAttackRelease("C4", "2n");\n * @category Instrument\n */\nclass DuoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(DuoSynth.getDefaults(), arguments));\n this.name = "DuoSynth";\n const options = optionsFromArguments(DuoSynth.getDefaults(), arguments);\n this.voice0 = new MonoSynth(Object.assign(options.voice0, {\n context: this.context,\n onsilence: () => this.onsilence(this)\n }));\n this.voice1 = new MonoSynth(Object.assign(options.voice1, {\n context: this.context,\n }));\n this.harmonicity = new Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this._vibrato = new LFO({\n frequency: options.vibratoRate,\n context: this.context,\n min: -50,\n max: 50\n });\n // start the vibrato immediately\n this._vibrato.start();\n this.vibratoRate = this._vibrato.frequency;\n this._vibratoGain = new Gain({\n context: this.context,\n units: "normalRange",\n gain: options.vibratoAmount\n });\n this.vibratoAmount = this._vibratoGain.gain;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: 440\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune\n });\n // control the two voices frequency\n this.frequency.connect(this.voice0.frequency);\n this.frequency.chain(this.harmonicity, this.voice1.frequency);\n this._vibrato.connect(this._vibratoGain);\n this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);\n this.detune.fan(this.voice0.detune, this.voice1.detune);\n this.voice0.connect(this.output);\n this.voice1.connect(this.output);\n readOnly(this, ["voice0", "voice1", "frequency", "vibratoAmount", "vibratoRate"]);\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.voice0.envelope.getValueAtTime(time) + this.voice1.envelope.getValueAtTime(time);\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n vibratoAmount: 0.5,\n vibratoRate: 5,\n harmonicity: 1.5,\n voice0: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n voice1: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this.voice0._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this.voice1._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this.voice0._triggerEnvelopeRelease(time);\n // @ts-ignore\n this.voice1._triggerEnvelopeRelease(time);\n return this;\n }\n dispose() {\n super.dispose();\n this.voice0.dispose();\n this.voice1.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._vibrato.dispose();\n this.vibratoRate.dispose();\n this._vibratoGain.dispose();\n this.harmonicity.dispose();\n return this;\n }\n}\n//# sourceMappingURL=DuoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/FMSynth.js\n\n\n\n/**\n * FMSynth is composed of two Tone.Synths where one Tone.Synth modulates\n * the frequency of a second Tone.Synth. A lot of spectral content\n * can be explored using the modulationIndex parameter. Read more about\n * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm).\n *\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.triggerAttackRelease("C5", "4n");\n *\n * @category Instrument\n */\nclass FMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(FMSynth.getDefaults(), arguments));\n this.name = "FMSynth";\n const options = optionsFromArguments(FMSynth.getDefaults(), arguments);\n this.modulationIndex = new Multiply({\n context: this.context,\n value: options.modulationIndex,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ModulationSynth.getDefaults(), {\n modulationIndex: 10,\n });\n }\n dispose() {\n super.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MetalSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Inharmonic ratio of frequencies based on the Roland TR-808\n * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model\n */\nconst inharmRatios = (/* unused pure expression or super */ null && ([1.0, 1.483, 1.932, 2.546, 2.630, 3.897]));\n/**\n * A highly inharmonic and spectrally complex source with a highpass filter\n * and amplitude envelope which is good for making metallophone sounds.\n * Based on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).\n * Inspiration from [Sound on Sound](https://shorturl.at/rSZ12).\n * @category Instrument\n */\nclass MetalSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MetalSynth.getDefaults(), arguments));\n this.name = "MetalSynth";\n /**\n * The array of FMOscillators\n */\n this._oscillators = [];\n /**\n * The frequency multipliers\n */\n this._freqMultipliers = [];\n const options = optionsFromArguments(MetalSynth.getDefaults(), arguments);\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this._amplitude = new Gain({\n context: this.context,\n gain: 0,\n }).connect(this.output);\n this._highpass = new Filter({\n // Q: -3.0102999566398125,\n Q: 0,\n context: this.context,\n type: "highpass",\n }).connect(this._amplitude);\n for (let i = 0; i < inharmRatios.length; i++) {\n const osc = new FMOscillator({\n context: this.context,\n harmonicity: options.harmonicity,\n modulationIndex: options.modulationIndex,\n modulationType: "square",\n onstop: i === 0 ? () => this.onsilence(this) : noOp,\n type: "square",\n });\n osc.connect(this._highpass);\n this._oscillators[i] = osc;\n const mult = new Multiply({\n context: this.context,\n value: inharmRatios[i],\n });\n this._freqMultipliers[i] = mult;\n this.frequency.chain(mult, osc.frequency);\n this.detune.connect(osc.detune);\n }\n this._filterFreqScaler = new Scale({\n context: this.context,\n max: 7000,\n min: this.toFrequency(options.resonance),\n });\n this.envelope = new Envelope({\n attack: options.envelope.attack,\n attackCurve: "linear",\n context: this.context,\n decay: options.envelope.decay,\n release: options.envelope.release,\n sustain: 0,\n });\n this.envelope.chain(this._filterFreqScaler, this._highpass.frequency);\n this.envelope.connect(this._amplitude.gain);\n // set the octaves\n this._octaves = options.octaves;\n this.octaves = options.octaves;\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.001,\n decay: 1.4,\n release: 0.2,\n }),\n harmonicity: 5.1,\n modulationIndex: 32,\n octaves: 1.5,\n resonance: 4000,\n });\n }\n /**\n * Trigger the attack.\n * @param time When the attack should be triggered.\n * @param velocity The velocity that the envelope should be triggered at.\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this._oscillators.forEach(osc => osc.start(time));\n if (this.envelope.sustain === 0) {\n this._oscillators.forEach(osc => {\n osc.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n });\n }\n return this;\n }\n /**\n * Trigger the release of the envelope.\n * @param time When the release should be triggered.\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this._oscillators.forEach(osc => osc.stop(time + this.toSeconds(this.envelope.release)));\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * The modulationIndex of the oscillators which make up the source.\n * see [[FMOscillator.modulationIndex]]\n * @min 1\n * @max 100\n */\n get modulationIndex() {\n return this._oscillators[0].modulationIndex.value;\n }\n set modulationIndex(val) {\n this._oscillators.forEach(osc => (osc.modulationIndex.value = val));\n }\n /**\n * The harmonicity of the oscillators which make up the source.\n * see Tone.FMOscillator.harmonicity\n * @min 0.1\n * @max 10\n */\n get harmonicity() {\n return this._oscillators[0].harmonicity.value;\n }\n set harmonicity(val) {\n this._oscillators.forEach(osc => (osc.harmonicity.value = val));\n }\n /**\n * The lower level of the highpass filter which is attached to the envelope.\n * This value should be between [0, 7000]\n * @min 0\n * @max 7000\n */\n get resonance() {\n return this._filterFreqScaler.min;\n }\n set resonance(val) {\n this._filterFreqScaler.min = this.toFrequency(val);\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the "resonance" frequency\n * that the filter ramps during the attack/decay envelope\n * @min 0\n * @max 8\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(val) {\n this._octaves = val;\n this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, val);\n }\n dispose() {\n super.dispose();\n this._oscillators.forEach(osc => osc.dispose());\n this._freqMultipliers.forEach(freqMult => freqMult.dispose());\n this.frequency.dispose();\n this.detune.dispose();\n this._filterFreqScaler.dispose();\n this._amplitude.dispose();\n this.envelope.dispose();\n this._highpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MetalSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MembraneSynth.js\n\n\n\n\n\n\n\n/**\n * MembraneSynth makes kick and tom sounds using a single oscillator\n * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator\n * is routed through a Tone.AmplitudeEnvelope to the output. The drum\n * quality of the sound comes from the frequency envelope applied\n * during MembraneSynth.triggerAttack(note). The frequency envelope\n * starts at <code>note * .octaves</code> and ramps to <code>note</code>\n * over the duration of <code>.pitchDecay</code>.\n * @example\n * const synth = new Tone.MembraneSynth().toDestination();\n * synth.triggerAttackRelease("C2", "8n");\n * @category Instrument\n */\nclass MembraneSynth extends Synth_Synth {\n constructor() {\n super(Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments));\n this.name = "MembraneSynth";\n /**\n * Portamento is ignored in this synth. use pitch decay instead.\n */\n this.portamento = 0;\n const options = Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments);\n this.pitchDecay = options.pitchDecay;\n this.octaves = options.octaves;\n Interface_readOnly(this, ["oscillator", "envelope"]);\n }\n static getDefaults() {\n return Defaults_deepMerge(Monophonic_Monophonic.getDefaults(), Synth_Synth.getDefaults(), {\n envelope: {\n attack: 0.001,\n attackCurve: "exponential",\n decay: 0.4,\n release: 1.4,\n sustain: 0.01,\n },\n octaves: 10,\n oscillator: {\n type: "sine",\n },\n pitchDecay: 0.05,\n });\n }\n setNote(note, time) {\n const seconds = this.toSeconds(time);\n const hertz = this.toFrequency(note instanceof Frequency_FrequencyClass ? note.toFrequency() : note);\n const maxNote = hertz * this.octaves;\n this.oscillator.frequency.setValueAtTime(maxNote, seconds);\n this.oscillator.frequency.exponentialRampToValueAtTime(hertz, seconds + this.toSeconds(this.pitchDecay));\n return this;\n }\n dispose() {\n super.dispose();\n return this;\n }\n}\n__decorate([\n range(0)\n], MembraneSynth.prototype, "octaves", void 0);\n__decorate([\n timeRange(0)\n], MembraneSynth.prototype, "pitchDecay", void 0);\n//# sourceMappingURL=MembraneSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/NoiseSynth.js\n\n\n\n\n\n\n\n/**\n * Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]].\n * ```\n * +-------+ +-------------------+\n * | Noise +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +-------+ +-------------------+\n * ```\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttackRelease("8n", 0.05);\n * @category Instrument\n */\nclass NoiseSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(NoiseSynth.getDefaults(), arguments));\n this.name = "NoiseSynth";\n const options = optionsFromArguments(NoiseSynth.getDefaults(), arguments);\n this.noise = new Noise(Object.assign({\n context: this.context,\n }, options.noise));\n this.envelope = new AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the noise to the output\n this.noise.chain(this.envelope, this.output);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n decay: 0.1,\n sustain: 0.0,\n }),\n noise: Object.assign(omitFromObject(Noise.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "white",\n }),\n });\n }\n /**\n * Start the attack portion of the envelopes. Unlike other\n * instruments, Tone.NoiseSynth doesn\'t have a note.\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttack();\n */\n triggerAttack(time, velocity = 1) {\n time = this.toSeconds(time);\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n // start the noise\n this.noise.start(time);\n if (this.envelope.sustain === 0) {\n this.noise.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n }\n return this;\n }\n /**\n * Start the release portion of the envelopes.\n */\n triggerRelease(time) {\n time = this.toSeconds(time);\n this.envelope.triggerRelease(time);\n this.noise.stop(time + this.toSeconds(this.envelope.release));\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 0);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n duration = this.toSeconds(duration);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + duration);\n return this;\n }\n dispose() {\n super.dispose();\n this.noise.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=NoiseSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/WorkletGlobalScope.js\n/**\n * All of the classes or functions which are loaded into the AudioWorkletGlobalScope\n */\nconst workletContext = new Set();\n/**\n * Add a class to the AudioWorkletGlobalScope\n */\nfunction addToWorklet(classOrFunction) {\n workletContext.add(classOrFunction);\n}\n/**\n * Register a processor in the AudioWorkletGlobalScope with the given name\n */\nfunction registerProcessor(name, classDesc) {\n const processor = /* javascript */ `registerProcessor("${name}", ${classDesc})`;\n workletContext.add(processor);\n}\n/**\n * Get all of the modules which have been registered to the AudioWorkletGlobalScope\n */\nfunction WorkletGlobalScope_getWorkletGlobalScope() {\n return Array.from(workletContext).join("\\n");\n}\n//# sourceMappingURL=WorkletGlobalScope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorklet.js\n\n\n\nclass ToneAudioWorklet_ToneAudioWorklet extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "ToneAudioWorklet";\n /**\n * The constructor options for the node\n */\n this.workletOptions = {};\n /**\n * Callback which is invoked when there is an error in the processing\n */\n this.onprocessorerror = noOp;\n const blobUrl = URL.createObjectURL(new Blob([getWorkletGlobalScope()], { type: "text/javascript" }));\n const name = this._audioWorkletName();\n this._dummyGain = this.context.createGain();\n this._dummyParam = this._dummyGain.gain;\n // Register the processor\n this.context.addAudioWorkletModule(blobUrl, name).then(() => {\n // create the worklet when it\'s read\n if (!this.disposed) {\n this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions);\n this._worklet.onprocessorerror = this.onprocessorerror.bind(this);\n this.onReady(this._worklet);\n }\n });\n }\n dispose() {\n super.dispose();\n this._dummyGain.disconnect();\n if (this._worklet) {\n this._worklet.port.postMessage("dispose");\n this._worklet.disconnect();\n }\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioWorklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorkletProcessor.worklet.js\n\nconst toneAudioWorkletProcessor = /* javascript */ `\n\t/**\n\t * The base AudioWorkletProcessor for use in Tone.js. Works with the [[ToneAudioWorklet]]. \n\t */\n\tclass ToneAudioWorkletProcessor extends AudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\t\n\t\t\tsuper(options);\n\t\t\t/**\n\t\t\t * If the processor was disposed or not. Keep alive until it\'s disposed.\n\t\t\t */\n\t\t\tthis.disposed = false;\n\t\t \t/** \n\t\t\t * The number of samples in the processing block\n\t\t\t */\n\t\t\tthis.blockSize = 128;\n\t\t\t/**\n\t\t\t * the sample rate\n\t\t\t */\n\t\t\tthis.sampleRate = sampleRate;\n\n\t\t\tthis.port.onmessage = (event) => {\n\t\t\t\t// when it receives a dispose \n\t\t\t\tif (event.data === "dispose") {\n\t\t\t\t\tthis.disposed = true;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n`;\naddToWorklet(toneAudioWorkletProcessor);\n//# sourceMappingURL=ToneAudioWorkletProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/SingleIOProcessor.worklet.js\n\n\nconst singleIOProcess = /* javascript */ `\n\t/**\n\t * Abstract class for a single input/output processor. \n\t * has a \'generate\' function which processes one sample at a time\n\t */\n\tclass SingleIOProcessor extends ToneAudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(Object.assign(options, {\n\t\t\t\tnumberOfInputs: 1,\n\t\t\t\tnumberOfOutputs: 1\n\t\t\t}));\n\t\t\t/**\n\t\t\t * Holds the name of the parameter and a single value of that\n\t\t\t * parameter at the current sample\n\t\t\t * @type { [name: string]: number }\n\t\t\t */\n\t\t\tthis.params = {}\n\t\t}\n\n\t\t/**\n\t\t * Generate an output sample from the input sample and parameters\n\t\t * @abstract\n\t\t * @param input number\n\t\t * @param channel number\n\t\t * @param parameters { [name: string]: number }\n\t\t * @returns number\n\t\t */\n\t\tgenerate(){}\n\n\t\t/**\n\t\t * Update the private params object with the \n\t\t * values of the parameters at the given index\n\t\t * @param parameters { [name: string]: Float32Array },\n\t\t * @param index number\n\t\t */\n\t\tupdateParams(parameters, index) {\n\t\t\tfor (const paramName in parameters) {\n\t\t\t\tconst param = parameters[paramName];\n\t\t\t\tif (param.length > 1) {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][index];\n\t\t\t\t} else {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][0];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Process a single frame of the audio\n\t\t * @param inputs Float32Array[][]\n\t\t * @param outputs Float32Array[][]\n\t\t */\n\t\tprocess(inputs, outputs, parameters) {\n\t\t\tconst input = inputs[0];\n\t\t\tconst output = outputs[0];\n\t\t\t// get the parameter values\n\t\t\tconst channelCount = Math.max(input && input.length || 0, output.length);\n\t\t\tfor (let sample = 0; sample < this.blockSize; sample++) {\n\t\t\t\tthis.updateParams(parameters, sample);\n\t\t\t\tfor (let channel = 0; channel < channelCount; channel++) {\n\t\t\t\t\tconst inputSample = input && input.length ? input[channel][sample] : 0;\n\t\t\t\t\toutput[channel][sample] = this.generate(inputSample, channel, this.params);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn !this.disposed;\n\t\t}\n\t};\n`;\naddToWorklet(singleIOProcess);\n//# sourceMappingURL=SingleIOProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/DelayLine.worklet.js\n\nconst delayLine = /* javascript */ `\n\t/**\n\t * A multichannel buffer for use within an AudioWorkletProcessor as a delay line\n\t */\n\tclass DelayLine {\n\t\t\n\t\tconstructor(size, channels) {\n\t\t\tthis.buffer = [];\n\t\t\tthis.writeHead = []\n\t\t\tthis.size = size;\n\n\t\t\t// create the empty channels\n\t\t\tfor (let i = 0; i < channels; i++) {\n\t\t\t\tthis.buffer[i] = new Float32Array(this.size);\n\t\t\t\tthis.writeHead[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Push a value onto the end\n\t\t * @param channel number\n\t\t * @param value number\n\t\t */\n\t\tpush(channel, value) {\n\t\t\tthis.writeHead[channel] += 1;\n\t\t\tif (this.writeHead[channel] > this.size) {\n\t\t\t\tthis.writeHead[channel] = 0;\n\t\t\t}\n\t\t\tthis.buffer[channel][this.writeHead[channel]] = value;\n\t\t}\n\n\t\t/**\n\t\t * Get the recorded value of the channel given the delay\n\t\t * @param channel number\n\t\t * @param delay number delay samples\n\t\t */\n\t\tget(channel, delay) {\n\t\t\tlet readHead = this.writeHead[channel] - Math.floor(delay);\n\t\t\tif (readHead < 0) {\n\t\t\t\treadHead += this.size;\n\t\t\t}\n\t\t\treturn this.buffer[channel][readHead];\n\t\t}\n\t}\n`;\naddToWorklet(delayLine);\n//# sourceMappingURL=DelayLine.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.worklet.js\n\n\n\nconst FeedbackCombFilter_worklet_workletName = "feedback-comb-filter";\nconst feedbackCombFilter = /* javascript */ `\n\tclass FeedbackCombFilterWorklet extends SingleIOProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(options);\n\t\t\tthis.delayLine = new DelayLine(this.sampleRate, options.channelCount || 2);\n\t\t}\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "delayTime",\n\t\t\t\tdefaultValue: 0.1,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 1,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}, {\n\t\t\t\tname: "feedback",\n\t\t\t\tdefaultValue: 0.5,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 0.9999,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, channel, parameters) {\n\t\t\tconst delayedSample = this.delayLine.get(channel, parameters.delayTime * this.sampleRate);\n\t\t\tthis.delayLine.push(channel, input + delayedSample * parameters.feedback);\n\t\t\treturn delayedSample;\n\t\t}\n\t}\n`;\nregisterProcessor(FeedbackCombFilter_worklet_workletName, feedbackCombFilter);\n//# sourceMappingURL=FeedbackCombFilter.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.js\n\n\n\n\n\n\n\n/**\n * Comb filters are basic building blocks for physical modeling. Read more\n * about comb filters on [CCRMA\'s website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html).\n *\n * This comb filter is implemented with the AudioWorkletNode which allows it to have feedback delays less than the\n * Web Audio processing block of 128 samples. There is a polyfill for browsers that don\'t yet support the\n * AudioWorkletNode, but it will add some latency and have slower performance than the AudioWorkletNode.\n * @category Component\n */\nclass FeedbackCombFilter_FeedbackCombFilter extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]));\n this.name = "FeedbackCombFilter";\n const options = optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.delayTime = new Param({\n context: this.context,\n value: options.delayTime,\n units: "time",\n minValue: 0,\n maxValue: 1,\n param: this._dummyParam,\n swappable: true,\n });\n this.resonance = new Param({\n context: this.context,\n value: options.resonance,\n units: "normalRange",\n param: this._dummyParam,\n swappable: true,\n });\n readOnly(this, ["resonance", "delayTime"]);\n }\n _audioWorkletName() {\n return workletName;\n }\n /**\n * The default parameters\n */\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const delayTime = node.parameters.get("delayTime");\n ;\n this.delayTime.setParam(delayTime);\n const feedback = node.parameters.get("feedback");\n ;\n this.resonance.setParam(feedback);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.delayTime.dispose();\n this.resonance.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/OnePoleFilter.js\n\n\n\n/**\n * A one pole filter with 6db-per-octave rolloff. Either "highpass" or "lowpass".\n * Note that changing the type or frequency may result in a discontinuity which\n * can sound like a click or pop.\n * References:\n * * http://www.earlevel.com/main/2012/12/15/a-one-pole-filter/\n * * http://www.dspguide.com/ch19/2.htm\n * * https://github.com/vitaliy-bobrov/js-rocks/blob/master/src/app/audio/effects/one-pole-filters.ts\n * @category Component\n */\nclass OnePoleFilter_OnePoleFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OnePoleFilter";\n const options = optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._frequency = options.frequency;\n this._type = options.type;\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._createFilter();\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n frequency: 880,\n type: "lowpass"\n });\n }\n /**\n * Create a filter and dispose the old one\n */\n _createFilter() {\n const oldFilter = this._filter;\n const freq = this.toFrequency(this._frequency);\n const t = 1 / (2 * Math.PI * freq);\n if (this._type === "lowpass") {\n const a0 = 1 / (t * this.context.sampleRate);\n const b1 = a0 - 1;\n this._filter = this.context.createIIRFilter([a0, 0], [1, b1]);\n }\n else {\n const b1 = 1 / (t * this.context.sampleRate) - 1;\n this._filter = this.context.createIIRFilter([1, -1], [1, b1]);\n }\n this.input.chain(this._filter, this.output);\n if (oldFilter) {\n // dispose it on the next block\n this.context.setTimeout(() => {\n if (!this.disposed) {\n this.input.disconnect(oldFilter);\n oldFilter.disconnect();\n }\n }, this.blockTime);\n }\n }\n /**\n * The frequency value.\n */\n get frequency() {\n return this._frequency;\n }\n set frequency(fq) {\n this._frequency = fq;\n this._createFilter();\n }\n /**\n * The OnePole Filter type, either "highpass" or "lowpass"\n */\n get type() {\n return this._type;\n }\n set type(t) {\n this._type = t;\n this._createFilter();\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n this._filter.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this._filter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OnePoleFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/LowpassCombFilter.js\n\n\n\n\n/**\n * A lowpass feedback comb filter. It is similar to\n * [[FeedbackCombFilter]], but includes a lowpass filter.\n * @category Component\n */\nclass LowpassCombFilter_LowpassCombFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]));\n this.name = "LowpassCombFilter";\n const options = optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]);\n this._combFilter = this.output = new FeedbackCombFilter({\n context: this.context,\n delayTime: options.delayTime,\n resonance: options.resonance,\n });\n this.delayTime = this._combFilter.delayTime;\n this.resonance = this._combFilter.resonance;\n this._lowpass = this.input = new OnePoleFilter({\n context: this.context,\n frequency: options.dampening,\n type: "lowpass",\n });\n // connections\n this._lowpass.connect(this._combFilter);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n dampening: 3000,\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n /**\n * The dampening control of the feedback\n */\n get dampening() {\n return this._lowpass.frequency;\n }\n set dampening(fq) {\n this._lowpass.frequency = fq;\n }\n dispose() {\n super.dispose();\n this._combFilter.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LowpassCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PluckSynth.js\n\n\n\n\n\n/**\n * Karplus-String string synthesis.\n * @example\n * const plucky = new Tone.PluckSynth().toDestination();\n * plucky.triggerAttack("C4", "+0.5");\n * plucky.triggerAttack("C3", "+1");\n * plucky.triggerAttack("C2", "+1.5");\n * plucky.triggerAttack("C1", "+2");\n * @category Instrument\n */\nclass PluckSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PluckSynth.getDefaults(), arguments));\n this.name = "PluckSynth";\n const options = optionsFromArguments(PluckSynth.getDefaults(), arguments);\n this._noise = new Noise({\n context: this.context,\n type: "pink"\n });\n this.attackNoise = options.attackNoise;\n this._lfcf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n resonance: options.resonance,\n });\n this.resonance = options.resonance;\n this.release = options.release;\n this._noise.connect(this._lfcf);\n this._lfcf.connect(this.output);\n }\n static getDefaults() {\n return deepMerge(Instrument.getDefaults(), {\n attackNoise: 1,\n dampening: 4000,\n resonance: 0.7,\n release: 1,\n });\n }\n /**\n * The dampening control. i.e. the lowpass filter frequency of the comb filter\n * @min 0\n * @max 7000\n */\n get dampening() {\n return this._lfcf.dampening;\n }\n set dampening(fq) {\n this._lfcf.dampening = fq;\n }\n triggerAttack(note, time) {\n const freq = this.toFrequency(note);\n time = this.toSeconds(time);\n const delayAmount = 1 / freq;\n this._lfcf.delayTime.setValueAtTime(delayAmount, time);\n this._noise.start(time);\n this._noise.stop(time + delayAmount * this.attackNoise);\n this._lfcf.resonance.cancelScheduledValues(time);\n this._lfcf.resonance.setValueAtTime(this.resonance, time);\n return this;\n }\n /**\n * Ramp down the [[resonance]] to 0 over the duration of the release time.\n */\n triggerRelease(time) {\n this._lfcf.resonance.linearRampTo(0, this.release, time);\n return this;\n }\n dispose() {\n super.dispose();\n this._noise.dispose();\n this._lfcf.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PluckSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PolySynth.js\n\n\n\n\n\n\n/**\n * PolySynth handles voice creation and allocation for any\n * instruments passed in as the second paramter. PolySynth is\n * not a synthesizer by itself, it merely manages voices of\n * one of the other types of synths, allowing any of the\n * monophonic synthesizers to be polyphonic.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * // set the attributes across all the voices using \'set\'\n * synth.set({ detune: -1200 });\n * // play a chord\n * synth.triggerAttackRelease(["C4", "E4", "A4"], 1);\n * @category Instrument\n */\nclass PolySynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]));\n this.name = "PolySynth";\n /**\n * The voices which are not currently in use\n */\n this._availableVoices = [];\n /**\n * The currently active voices\n */\n this._activeVoices = [];\n /**\n * All of the allocated voices for this synth.\n */\n this._voices = [];\n /**\n * The GC timeout. Held so that it could be cancelled when the node is disposed.\n */\n this._gcTimeout = -1;\n /**\n * A moving average of the number of active voices\n */\n this._averageActiveVoices = 0;\n const options = optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]);\n // check against the old API (pre 14.3.0)\n assert(!isNumber(options.voice), "DEPRECATED: The polyphony count is no longer the first argument.");\n const defaults = options.voice.getDefaults();\n this.options = Object.assign(defaults, options.options);\n this.voice = options.voice;\n this.maxPolyphony = options.maxPolyphony;\n // create the first voice\n this._dummyVoice = this._getNextAvailableVoice();\n // remove it from the voices list\n const index = this._voices.indexOf(this._dummyVoice);\n this._voices.splice(index, 1);\n // kick off the GC interval\n this._gcTimeout = this.context.setInterval(this._collectGarbage.bind(this), 1);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n maxPolyphony: 32,\n options: {},\n voice: Synth,\n });\n }\n /**\n * The number of active voices.\n */\n get activeVoices() {\n return this._activeVoices.length;\n }\n /**\n * Invoked when the source is done making sound, so that it can be\n * readded to the pool of available voices\n */\n _makeVoiceAvailable(voice) {\n this._availableVoices.push(voice);\n // remove the midi note from \'active voices\'\n const activeVoiceIndex = this._activeVoices.findIndex((e) => e.voice === voice);\n this._activeVoices.splice(activeVoiceIndex, 1);\n }\n /**\n * Get an available voice from the pool of available voices.\n * If one is not available and the maxPolyphony limit is reached,\n * steal a voice, otherwise return null.\n */\n _getNextAvailableVoice() {\n // if there are available voices, return the first one\n if (this._availableVoices.length) {\n return this._availableVoices.shift();\n }\n else if (this._voices.length < this.maxPolyphony) {\n // otherwise if there is still more maxPolyphony, make a new voice\n const voice = new this.voice(Object.assign(this.options, {\n context: this.context,\n onsilence: this._makeVoiceAvailable.bind(this),\n }));\n voice.connect(this.output);\n this._voices.push(voice);\n return voice;\n }\n else {\n warn("Max polyphony exceeded. Note dropped.");\n }\n }\n /**\n * Occasionally check if there are any allocated voices which can be cleaned up.\n */\n _collectGarbage() {\n this._averageActiveVoices = Math.max(this._averageActiveVoices * 0.95, this.activeVoices);\n if (this._availableVoices.length && this._voices.length > Math.ceil(this._averageActiveVoices + 1)) {\n // take off an available note\n const firstAvail = this._availableVoices.shift();\n const index = this._voices.indexOf(firstAvail);\n this._voices.splice(index, 1);\n if (!this.context.isOffline) {\n firstAvail.dispose();\n }\n }\n }\n /**\n * Internal method which triggers the attack\n */\n _triggerAttack(notes, time, velocity) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const voice = this._getNextAvailableVoice();\n if (voice) {\n voice.triggerAttack(note, time, velocity);\n this._activeVoices.push({\n midi: midiNote, voice, released: false,\n });\n this.log("triggerAttack", note, time);\n }\n });\n }\n /**\n * Internal method which triggers the release\n */\n _triggerRelease(notes, time) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const event = this._activeVoices.find(({ midi, released }) => midi === midiNote && !released);\n if (event) {\n // trigger release on that note\n event.voice.triggerRelease(time);\n // mark it as released\n event.released = true;\n this.log("triggerRelease", note, time);\n }\n });\n }\n /**\n * Schedule the attack/release events. If the time is in the future, then it should set a timeout\n * to wait for just-in-time scheduling\n */\n _scheduleEvent(type, notes, time, velocity) {\n assert(!this.disposed, "Synth was already disposed");\n // if the notes are greater than this amount of time in the future, they should be scheduled with setTimeout\n if (time <= this.now()) {\n // do it immediately\n if (type === "attack") {\n this._triggerAttack(notes, time, velocity);\n }\n else {\n this._triggerRelease(notes, time);\n }\n }\n else {\n // schedule it to start in the future\n this.context.setTimeout(() => {\n this._scheduleEvent(type, notes, time, velocity);\n }, time - this.now());\n }\n }\n /**\n * Trigger the attack portion of the note\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time The start time of the note.\n * @param velocity The velocity of the note.\n * @example\n * const synth = new Tone.PolySynth(Tone.FMSynth).toDestination();\n * // trigger a chord immediately with a velocity of 0.2\n * synth.triggerAttack(["Ab3", "C4", "F5"], Tone.now(), 0.2);\n */\n triggerAttack(notes, time, velocity) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("attack", notes, computedTime, velocity);\n return this;\n }\n /**\n * Trigger the release of the note. Unlike monophonic instruments,\n * a note (or array of notes) needs to be passed in as the first argument.\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time When the release will be triggered.\n * @example\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * poly.triggerAttack(["Ab3", "C4", "F5"]);\n * // trigger the release of the given notes.\n * poly.triggerRelease(["Ab3", "C4"], "+1");\n * poly.triggerRelease("F5", "+3");\n */\n triggerRelease(notes, time) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("release", notes, computedTime);\n return this;\n }\n /**\n * Trigger the attack and release after the specified duration\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param duration the duration of the note\n * @param time if no time is given, defaults to now\n * @param velocity the velocity of the attack (0-1)\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * // can pass in an array of durations as well\n * poly.triggerAttackRelease(["Eb3", "G4", "Bb4", "D5"], [4, 3, 2, 1]);\n */\n triggerAttackRelease(notes, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (isArray(duration)) {\n assert(isArray(notes), "If the duration is an array, the notes must also be an array");\n notes = notes;\n for (let i = 0; i < notes.length; i++) {\n const d = duration[Math.min(i, duration.length - 1)];\n const durationSeconds = this.toSeconds(d);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes[i], computedTime + durationSeconds);\n }\n }\n else {\n const durationSeconds = this.toSeconds(duration);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes, computedTime + durationSeconds);\n }\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Set a member/attribute of the voices\n * @example\n * const poly = new Tone.PolySynth().toDestination();\n * // set all of the voices using an options object for the synth type\n * poly.set({\n * \tenvelope: {\n * \t\tattack: 0.25\n * \t}\n * });\n * poly.triggerAttackRelease("Bb3", 0.2);\n */\n set(options) {\n // remove options which are controlled by the PolySynth\n const sanitizedOptions = omitFromObject(options, ["onsilence", "context"]);\n // store all of the options\n this.options = deepMerge(this.options, sanitizedOptions);\n this._voices.forEach(voice => voice.set(sanitizedOptions));\n this._dummyVoice.set(sanitizedOptions);\n return this;\n }\n get() {\n return this._dummyVoice.get();\n }\n /**\n * Trigger the release portion of all the currently active voices immediately.\n * Useful for silencing the synth.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeVoices.forEach(({ voice }) => {\n voice.triggerRelease(computedTime);\n });\n return this;\n }\n dispose() {\n super.dispose();\n this._dummyVoice.dispose();\n this._voices.forEach(v => v.dispose());\n this._activeVoices = [];\n this._availableVoices = [];\n this.context.clearInterval(this._gcTimeout);\n return this;\n }\n}\n//# sourceMappingURL=PolySynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Sampler.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Pass in an object which maps the note\'s pitch or midi value to the url,\n * then you can trigger the attack and release of that note like other instruments.\n * By automatically repitching the samples, it is possible to play pitches which\n * were not explicitly included which can save loading time.\n *\n * For sample or buffer playback where repitching is not necessary,\n * use [[Player]].\n * @example\n * const sampler = new Tone.Sampler({\n * \turls: {\n * \t\tA1: "A1.mp3",\n * \t\tA2: "A2.mp3",\n * \t},\n * \tbaseUrl: "https://tonejs.github.io/audio/casio/",\n * \tonload: () => {\n * \t\tsampler.triggerAttackRelease(["C1", "E1", "G1", "B1"], 0.5);\n * \t}\n * }).toDestination();\n * @category Instrument\n */\nclass Sampler extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls"));\n this.name = "Sampler";\n /**\n * The object of all currently playing BufferSources\n */\n this._activeSources = new Map();\n const options = Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n const urlMap = {};\n Object.keys(options.urls).forEach((note) => {\n const noteNumber = parseInt(note, 10);\n Debug_assert(isNote(note)\n || (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)), `url key is neither a note or midi pitch: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n urlMap[mid] = options.urls[note];\n }\n else if (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)) {\n // otherwise if it\'s numbers assume it\'s midi\n urlMap[noteNumber] = options.urls[noteNumber];\n }\n });\n this._buffers = new ToneAudioBuffers_ToneAudioBuffers({\n urls: urlMap,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror,\n });\n this.attack = options.attack;\n this.release = options.release;\n this.curve = options.curve;\n // invoke the callback if it\'s already loaded\n if (this._buffers.loaded) {\n // invoke onload deferred\n Promise.resolve().then(options.onload);\n }\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n attack: 0,\n baseUrl: "",\n curve: "exponential",\n onload: Interface_noOp,\n onerror: Interface_noOp,\n release: 0.1,\n urls: {},\n });\n }\n /**\n * Returns the difference in steps between the given midi note at the closets sample.\n */\n _findClosest(midi) {\n // searches within 8 octaves of the given midi note\n const MAX_INTERVAL = 96;\n let interval = 0;\n while (interval < MAX_INTERVAL) {\n // check above and below\n if (this._buffers.has(midi + interval)) {\n return -interval;\n }\n else if (this._buffers.has(midi - interval)) {\n return interval;\n }\n interval++;\n }\n throw new Error(`No available buffers for note: ${midi}`);\n }\n /**\n * @param notes\tThe note to play, or an array of notes.\n * @param time When to play the note\n * @param velocity The velocity to play the sample back.\n */\n triggerAttack(notes, time, velocity = 1) {\n this.log("triggerAttack", notes, time, velocity);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midiFloat = ftomf(new Frequency_FrequencyClass(this.context, note).toFrequency());\n const midi = Math.round(midiFloat);\n const remainder = midiFloat - midi;\n // find the closest note pitch\n const difference = this._findClosest(midi);\n const closestNote = midi - difference;\n const buffer = this._buffers.get(closestNote);\n const playbackRate = Conversions_intervalToFrequencyRatio(difference + remainder);\n // play that note\n const source = new ToneBufferSource_ToneBufferSource({\n url: buffer,\n context: this.context,\n curve: this.curve,\n fadeIn: this.attack,\n fadeOut: this.release,\n playbackRate,\n }).connect(this.output);\n source.start(time, 0, buffer.duration / playbackRate, velocity);\n // add it to the active sources\n if (!TypeCheck_isArray(this._activeSources.get(midi))) {\n this._activeSources.set(midi, []);\n }\n this._activeSources.get(midi).push(source);\n // remove it when it\'s done\n source.onended = () => {\n if (this._activeSources && this._activeSources.has(midi)) {\n const sources = this._activeSources.get(midi);\n const index = sources.indexOf(source);\n if (index !== -1) {\n sources.splice(index, 1);\n }\n }\n };\n });\n return this;\n }\n /**\n * @param notes\tThe note to release, or an array of notes.\n * @param time \tWhen to release the note.\n */\n triggerRelease(notes, time) {\n this.log("triggerRelease", notes, time);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midi = new Frequency_FrequencyClass(this.context, note).toMidi();\n // find the note\n if (this._activeSources.has(midi) && this._activeSources.get(midi).length) {\n const sources = this._activeSources.get(midi);\n time = this.toSeconds(time);\n sources.forEach(source => {\n source.stop(time);\n });\n this._activeSources.set(midi, []);\n }\n });\n return this;\n }\n /**\n * Release all currently active notes.\n * @param time \tWhen to release the notes.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(sources => {\n while (sources.length) {\n const source = sources.shift();\n source.stop(computedTime);\n }\n });\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Invoke the attack phase, then after the duration, invoke the release.\n * @param notes\tThe note to play and release, or an array of notes.\n * @param duration The time the note should be held\n * @param time When to start the attack\n * @param velocity The velocity of the attack\n */\n triggerAttackRelease(notes, duration, time, velocity = 1) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (TypeCheck_isArray(duration)) {\n Debug_assert(TypeCheck_isArray(notes), "notes must be an array when duration is array");\n notes.forEach((note, index) => {\n const d = duration[Math.min(index, duration.length - 1)];\n this.triggerRelease(note, computedTime + this.toSeconds(d));\n });\n }\n else {\n this.triggerRelease(notes, computedTime + this.toSeconds(duration));\n }\n return this;\n }\n /**\n * Add a note to the sampler.\n * @param note The buffer\'s pitch.\n * @param url Either the url of the buffer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(note, url, callback) {\n Debug_assert(isNote(note) || isFinite(note), `note must be a pitch or midi: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n this._buffers.add(mid, url, callback);\n }\n else {\n // otherwise if it\'s numbers assume it\'s midi\n this._buffers.add(note, url, callback);\n }\n return this;\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._buffers.dispose();\n this._activeSources.forEach(sources => {\n sources.forEach(source => source.dispose());\n });\n this._activeSources.clear();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Sampler.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Sampler.prototype, "release", void 0);\n//# sourceMappingURL=Sampler.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/index.js\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/ToneEvent.js\n\n\n\n\n\n\n\n/**\n * ToneEvent abstracts away this.context.transport.schedule and provides a schedulable\n * callback for a single or repeatable events along the timeline.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * const chordEvent = new Tone.ToneEvent(((time, chord) => {\n * \t// the chord as well as the exact time of the event\n * \t// are passed in as arguments to the callback function\n * \tsynth.triggerAttackRelease(chord, 0.5, time);\n * }), ["D4", "E4", "F4"]);\n * // start the chord at the beginning of the transport timeline\n * chordEvent.start();\n * // loop it every measure for 8 measures\n * chordEvent.loop = 8;\n * chordEvent.loopEnd = "1m";\n * @category Event\n */\nclass ToneEvent_ToneEvent extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]));\n this.name = "ToneEvent";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * A delay time from when the event is scheduled to start\n */\n this._startOffset = 0;\n const options = optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]);\n this._loop = options.loop;\n this.callback = options.callback;\n this.value = options.value;\n this._loopStart = this.toTicks(options.loopStart);\n this._loopEnd = this.toTicks(options.loopEnd);\n this._playbackRate = options.playbackRate;\n this._probability = options.probability;\n this._humanize = options.humanize;\n this.mute = options.mute;\n this._playbackRate = options.playbackRate;\n this._state.increasing = true;\n // schedule the events for the first time\n this._rescheduleEvents();\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n callback: noOp,\n humanize: false,\n loop: false,\n loopEnd: "1m",\n loopStart: 0,\n mute: false,\n playbackRate: 1,\n probability: 1,\n value: null,\n });\n }\n /**\n * Reschedule all of the events along the timeline\n * with the updated values.\n * @param after Only reschedules events after the given time.\n */\n _rescheduleEvents(after = -1) {\n // if no argument is given, schedules all of the events\n this._state.forEachFrom(after, event => {\n let duration;\n if (event.state === "started") {\n if (event.id !== -1) {\n this.context.transport.clear(event.id);\n }\n const startTick = event.time + Math.round(this.startOffset / this._playbackRate);\n if (this._loop === true || isNumber(this._loop) && this._loop > 1) {\n duration = Infinity;\n if (isNumber(this._loop)) {\n duration = (this._loop) * this._getLoopDuration();\n }\n const nextEvent = this._state.getAfter(startTick);\n if (nextEvent !== null) {\n duration = Math.min(duration, nextEvent.time - startTick);\n }\n if (duration !== Infinity) {\n // schedule a stop since it\'s finite duration\n this._state.setStateAtTime("stopped", startTick + duration + 1, { id: -1 });\n duration = new TicksClass(this.context, duration);\n }\n const interval = new TicksClass(this.context, this._getLoopDuration());\n event.id = this.context.transport.scheduleRepeat(this._tick.bind(this), interval, new TicksClass(this.context, startTick), duration);\n }\n else {\n event.id = this.context.transport.schedule(this._tick.bind(this), new TicksClass(this.context, startTick));\n }\n }\n });\n }\n /**\n * Returns the playback state of the note, either "started" or "stopped".\n */\n get state() {\n return this._state.getValueAtTime(this.context.transport.ticks);\n }\n /**\n * The start from the scheduled start time.\n */\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n }\n /**\n * The probability of the notes being triggered.\n */\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n }\n /**\n * If set to true, will apply small random variation\n * to the callback time. If the value is given as a time, it will randomize\n * by that amount.\n * @example\n * const event = new Tone.ToneEvent();\n * event.humanize = true;\n */\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n }\n /**\n * Start the note at the given time.\n * @param time When the event should start.\n */\n start(time) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "stopped") {\n this._state.add({\n id: -1,\n state: "started",\n time: ticks,\n });\n this._rescheduleEvents(ticks);\n }\n return this;\n }\n /**\n * Stop the Event at the given time.\n * @param time When the event should stop.\n */\n stop(time) {\n this.cancel(time);\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "started") {\n this._state.setStateAtTime("stopped", ticks, { id: -1 });\n const previousEvent = this._state.getBefore(ticks);\n let reschedulTime = ticks;\n if (previousEvent !== null) {\n reschedulTime = previousEvent.time;\n }\n this._rescheduleEvents(reschedulTime);\n }\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n time = defaultArg(time, -Infinity);\n const ticks = this.toTicks(time);\n this._state.forEachFrom(ticks, event => {\n this.context.transport.clear(event.id);\n });\n this._state.cancel(ticks);\n return this;\n }\n /**\n * The callback function invoker. Also\n * checks if the Event is done playing\n * @param time The time of the event in seconds\n */\n _tick(time) {\n const ticks = this.context.transport.getTicksAtTime(time);\n if (!this.mute && this._state.getValueAtTime(ticks) === "started") {\n if (this.probability < 1 && Math.random() > this.probability) {\n return;\n }\n if (this.humanize) {\n let variation = 0.02;\n if (!isBoolean(this.humanize)) {\n variation = this.toSeconds(this.humanize);\n }\n time += (Math.random() * 2 - 1) * variation;\n }\n this.callback(time, this.value);\n }\n }\n /**\n * Get the duration of the loop.\n */\n _getLoopDuration() {\n return Math.round((this._loopEnd - this._loopStart) / this._playbackRate);\n }\n /**\n * If the note should loop or not\n * between ToneEvent.loopStart and\n * ToneEvent.loopEnd. If set to true,\n * the event will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._rescheduleEvents();\n }\n /**\n * The playback rate of the note. Defaults to 1.\n * @example\n * const note = new Tone.ToneEvent();\n * note.loop = true;\n * // repeat the note twice as fast\n * note.playbackRate = 2;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._rescheduleEvents();\n }\n /**\n * The loopEnd point is the time the event will loop\n * if ToneEvent.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The time when the loop should start.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The current progress of the loop interval.\n * Returns 0 if the event is not started yet or\n * it is not set to loop.\n */\n get progress() {\n if (this._loop) {\n const ticks = this.context.transport.ticks;\n const lastEvent = this._state.get(ticks);\n if (lastEvent !== null && lastEvent.state === "started") {\n const loopDuration = this._getLoopDuration();\n const progress = (ticks - lastEvent.time) % loopDuration;\n return progress / loopDuration;\n }\n else {\n return 0;\n }\n }\n else {\n return 0;\n }\n }\n dispose() {\n super.dispose();\n this.cancel();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Loop.js\n\n\n\n\n/**\n * Loop creates a looped callback at the\n * specified interval. The callback can be\n * started, stopped and scheduled along\n * the Transport\'s timeline.\n * @example\n * const loop = new Tone.Loop((time) => {\n * \t// triggered every eighth note.\n * \tconsole.log(time);\n * }, "8n").start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Loop_Loop extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]));\n this.name = "Loop";\n const options = optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]);\n this._event = new ToneEvent({\n context: this.context,\n callback: this._tick.bind(this),\n loop: true,\n loopEnd: options.interval,\n playbackRate: options.playbackRate,\n probability: options.probability\n });\n this.callback = options.callback;\n // set the iterations\n this.iterations = options.iterations;\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n interval: "4n",\n callback: noOp,\n playbackRate: 1,\n iterations: Infinity,\n probability: 1,\n mute: false,\n humanize: false\n });\n }\n /**\n * Start the loop at the specified time along the Transport\'s timeline.\n * @param time When to start the Loop.\n */\n start(time) {\n this._event.start(time);\n return this;\n }\n /**\n * Stop the loop at the given time.\n * @param time When to stop the Loop.\n */\n stop(time) {\n this._event.stop(time);\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n this._event.cancel(time);\n return this;\n }\n /**\n * Internal function called when the notes should be called\n * @param time The time the event occurs\n */\n _tick(time) {\n this.callback(time);\n }\n /**\n * The state of the Loop, either started or stopped.\n */\n get state() {\n return this._event.state;\n }\n /**\n * The progress of the loop as a value between 0-1. 0, when the loop is stopped or done iterating.\n */\n get progress() {\n return this._event.progress;\n }\n /**\n * The time between successive callbacks.\n * @example\n * const loop = new Tone.Loop();\n * loop.interval = "8n"; // loop every 8n\n */\n get interval() {\n return this._event.loopEnd;\n }\n set interval(interval) {\n this._event.loopEnd = interval;\n }\n /**\n * The playback rate of the loop. The normal playback rate is 1 (no change).\n * A `playbackRate` of 2 would be twice as fast.\n */\n get playbackRate() {\n return this._event.playbackRate;\n }\n set playbackRate(rate) {\n this._event.playbackRate = rate;\n }\n /**\n * Random variation +/-0.01s to the scheduled time.\n * Or give it a time value which it will randomize by.\n */\n get humanize() {\n return this._event.humanize;\n }\n set humanize(variation) {\n this._event.humanize = variation;\n }\n /**\n * The probably of the callback being invoked.\n */\n get probability() {\n return this._event.probability;\n }\n set probability(prob) {\n this._event.probability = prob;\n }\n /**\n * Muting the Loop means that no callbacks are invoked.\n */\n get mute() {\n return this._event.mute;\n }\n set mute(mute) {\n this._event.mute = mute;\n }\n /**\n * The number of iterations of the loop. The default value is `Infinity` (loop forever).\n */\n get iterations() {\n if (this._event.loop === true) {\n return Infinity;\n }\n else {\n return this._event.loop;\n }\n }\n set iterations(iters) {\n if (iters === Infinity) {\n this._event.loop = true;\n }\n else {\n this._event.loop = iters;\n }\n }\n dispose() {\n super.dispose();\n this._event.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Loop.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Part.js\n\n\n\n\n\n\n/**\n * Part is a collection ToneEvents which can be started/stopped and looped as a single unit.\n *\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const part = new Tone.Part(((time, note) => {\n * \t// the notes given as the second element in the array\n * \t// will be passed in as the second argument\n * \tsynth.triggerAttackRelease(note, "8n", time);\n * }), [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]);\n * Tone.Transport.start();\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // use an array of objects as long as the object has a "time" attribute\n * const part = new Tone.Part(((time, value) => {\n * \t// the value is an object which contains both the note and the velocity\n * \tsynth.triggerAttackRelease(value.note, "8n", time, value.velocity);\n * }), [{ time: 0, note: "C3", velocity: 0.9 },\n * \t{ time: "0:2", note: "C4", velocity: 0.5 }\n * ]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Part_Part extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]));\n this.name = "Part";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * The events that belong to this part\n */\n this._events = new Set();\n const options = optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]);\n // make sure things are assigned in the right order\n this._state.increasing = true;\n // add the events\n options.events.forEach(event => {\n if (isArray(event)) {\n this.add(event[0], event[1]);\n }\n else {\n this.add(event);\n }\n });\n }\n static getDefaults() {\n return Object.assign(ToneEvent.getDefaults(), {\n events: [],\n });\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset from the start of the part to begin playing at.\n */\n start(time, offset) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) !== "started") {\n offset = defaultArg(offset, this._loop ? this._loopStart : 0);\n if (this._loop) {\n offset = defaultArg(offset, this._loopStart);\n }\n else {\n offset = defaultArg(offset, 0);\n }\n const computedOffset = this.toTicks(offset);\n this._state.add({\n id: -1,\n offset: computedOffset,\n state: "started",\n time: ticks,\n });\n this._forEach(event => {\n this._startNote(event, ticks, computedOffset);\n });\n }\n return this;\n }\n /**\n * Start the event in the given event at the correct time given\n * the ticks and offset and looping.\n * @param event\n * @param ticks\n * @param offset\n */\n _startNote(event, ticks, offset) {\n ticks -= offset;\n if (this._loop) {\n if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) {\n if (event.startOffset < offset) {\n // start it on the next loop\n ticks += this._getLoopDuration();\n }\n event.start(new TicksClass(this.context, ticks));\n }\n else if (event.startOffset < this._loopStart && event.startOffset >= offset) {\n event.loop = false;\n event.start(new TicksClass(this.context, ticks));\n }\n }\n else if (event.startOffset >= offset) {\n event.start(new TicksClass(this.context, ticks));\n }\n }\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n this._forEach(event => {\n event.startOffset += this._startOffset;\n });\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n const ticks = this.toTicks(time);\n this._state.cancel(ticks);\n this._state.setStateAtTime("stopped", ticks);\n this._forEach(event => {\n event.stop(time);\n });\n return this;\n }\n /**\n * Get/Set an Event\'s value at the given time.\n * If a value is passed in and no event exists at\n * the given time, one will be created with that value.\n * If two events are at the same time, the first one will\n * be returned.\n * @example\n * const part = new Tone.Part();\n * part.at("1m"); // returns the part at the first measure\n * part.at("2m", "C2"); // set the value at "2m" to C2.\n * // if an event didn\'t exist at that time, it will be created.\n * @param time The time of the event to get or set.\n * @param value If a value is passed in, the value of the event at the given time will be set to it.\n */\n at(time, value) {\n const timeInTicks = new TransportTimeClass(this.context, time).toTicks();\n const tickTime = new TicksClass(this.context, 1).toSeconds();\n const iterator = this._events.values();\n let result = iterator.next();\n while (!result.done) {\n const event = result.value;\n if (Math.abs(timeInTicks - event.startOffset) < tickTime) {\n if (isDefined(value)) {\n event.value = value;\n }\n return event;\n }\n result = iterator.next();\n }\n // if there was no event at that time, create one\n if (isDefined(value)) {\n this.add(time, value);\n // return the new event\n return this.at(time);\n }\n else {\n return null;\n }\n }\n add(time, value) {\n // extract the parameters\n if (time instanceof Object && Reflect.has(time, "time")) {\n value = time;\n time = value.time;\n }\n const ticks = this.toTicks(time);\n let event;\n if (value instanceof ToneEvent) {\n event = value;\n event.callback = this._tick.bind(this);\n }\n else {\n event = new ToneEvent({\n callback: this._tick.bind(this),\n context: this.context,\n value,\n });\n }\n // the start offset\n event.startOffset = ticks;\n // initialize the values\n event.set({\n humanize: this.humanize,\n loop: this.loop,\n loopEnd: this.loopEnd,\n loopStart: this.loopStart,\n playbackRate: this.playbackRate,\n probability: this.probability,\n });\n this._events.add(event);\n // start the note if it should be played right now\n this._restartEvent(event);\n return this;\n }\n /**\n * Restart the given event\n */\n _restartEvent(event) {\n this._state.forEach((stateEvent) => {\n if (stateEvent.state === "started") {\n this._startNote(event, stateEvent.time, stateEvent.offset);\n }\n else {\n // stop the note\n event.stop(new TicksClass(this.context, stateEvent.time));\n }\n });\n }\n remove(time, value) {\n // extract the parameters\n if (isObject(time) && time.hasOwnProperty("time")) {\n value = time;\n time = value.time;\n }\n time = this.toTicks(time);\n this._events.forEach(event => {\n if (event.startOffset === time) {\n if (isUndef(value) || (isDefined(value) && event.value === value)) {\n this._events.delete(event);\n event.dispose();\n }\n }\n });\n return this;\n }\n /**\n * Remove all of the notes from the group.\n */\n clear() {\n this._forEach(event => event.dispose());\n this._events.clear();\n return this;\n }\n /**\n * Cancel scheduled state change events: i.e. "start" and "stop".\n * @param after The time after which to cancel the scheduled events.\n */\n cancel(after) {\n this._forEach(event => event.cancel(after));\n this._state.cancel(this.toTicks(after));\n return this;\n }\n /**\n * Iterate over all of the events\n */\n _forEach(callback) {\n if (this._events) {\n this._events.forEach(event => {\n if (event instanceof Part_Part) {\n event._forEach(callback);\n }\n else {\n callback(event);\n }\n });\n }\n return this;\n }\n /**\n * Set the attribute of all of the events\n * @param attr the attribute to set\n * @param value The value to set it to\n */\n _setAll(attr, value) {\n this._forEach(event => {\n event[attr] = value;\n });\n }\n /**\n * Internal tick method\n * @param time The time of the event in seconds\n */\n _tick(time, value) {\n if (!this.mute) {\n this.callback(time, value);\n }\n }\n /**\n * Determine if the event should be currently looping\n * given the loop boundries of this Part.\n * @param event The event to test\n */\n _testLoopBoundries(event) {\n if (this._loop && (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd)) {\n event.cancel(0);\n }\n else if (event.state === "stopped") {\n // reschedule it if it\'s stopped\n this._restartEvent(event);\n }\n }\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n this._setAll("probability", prob);\n }\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n this._setAll("humanize", variation);\n }\n /**\n * If the part should loop or not\n * between Part.loopStart and\n * Part.loopEnd. If set to true,\n * the part will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n * @example\n * const part = new Tone.Part();\n * // loop the part 8 times\n * part.loop = 8;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._forEach(event => {\n event.loopStart = this.loopStart;\n event.loopEnd = this.loopEnd;\n event.loop = loop;\n this._testLoopBoundries(event);\n });\n }\n /**\n * The loopEnd point determines when it will\n * loop if Part.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._forEach(event => {\n event.loopEnd = loopEnd;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The loopStart point determines when it will\n * loop if Part.loop is true.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._forEach(event => {\n event.loopStart = this.loopStart;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The playback rate of the part\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._setAll("playbackRate", rate);\n }\n /**\n * The number of scheduled notes in the part.\n */\n get length() {\n return this._events.size;\n }\n dispose() {\n super.dispose();\n this.clear();\n return this;\n }\n}\n//# sourceMappingURL=Part.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/PatternGenerator.js\n\n\n/**\n * Start at the first value and go up to the last\n */\nfunction* upPatternGen(values) {\n let index = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n index++;\n }\n}\n/**\n * Start at the last value and go down to 0\n */\nfunction* downPatternGen(values) {\n let index = values.length - 1;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n index--;\n }\n}\n/**\n * Infinitely yield the generator\n */\nfunction* infiniteGen(values, gen) {\n while (true) {\n yield* gen(values);\n }\n}\n/**\n * Make sure that the index is in the given range\n */\nfunction clampToArraySize(index, values) {\n return clamp(index, 0, values.length - 1);\n}\n/**\n * Alternate between two generators\n */\nfunction* alternatingGenerator(values, directionUp) {\n let index = directionUp ? 0 : values.length - 1;\n while (true) {\n index = clampToArraySize(index, values);\n yield values[index];\n if (directionUp) {\n index++;\n if (index >= values.length - 1) {\n directionUp = false;\n }\n }\n else {\n index--;\n if (index <= 0) {\n directionUp = true;\n }\n }\n }\n}\n/**\n * Starting from the bottom move up 2, down 1\n */\nfunction* jumpUp(values) {\n let index = 0;\n let stepIndex = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? 2 : -1);\n }\n}\n/**\n * Starting from the top move down 2, up 1\n */\nfunction* jumpDown(values) {\n let index = values.length - 1;\n let stepIndex = 0;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? -2 : 1);\n }\n}\n/**\n * Choose a random index each time\n */\nfunction* randomGen(values) {\n while (true) {\n const randomIndex = Math.floor(Math.random() * values.length);\n yield values[randomIndex];\n }\n}\n/**\n * Randomly go through all of the values once before choosing a new random order\n */\nfunction* randomOnce(values) {\n // create an array of indices\n const copy = [];\n for (let i = 0; i < values.length; i++) {\n copy.push(i);\n }\n while (copy.length > 0) {\n // random choose an index, and then remove it so it\'s not chosen again\n const randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);\n const index = clampToArraySize(randVal[0], values);\n yield values[index];\n }\n}\n/**\n * Randomly choose to walk up or down 1 index in the values array\n */\nfunction* randomWalk(values) {\n // randomly choose a starting index in the values array\n let index = Math.floor(Math.random() * values.length);\n while (true) {\n if (index === 0) {\n index++; // at bottom of array, so force upward step\n }\n else if (index === values.length - 1) {\n index--; // at top of array, so force downward step\n }\n else if (Math.random() < 0.5) { // else choose random downward or upward step\n index--;\n }\n else {\n index++;\n }\n yield values[index];\n }\n}\n/**\n * PatternGenerator returns a generator which will iterate over the given array\n * of values and yield the items according to the passed in pattern\n * @param values An array of values to iterate over\n * @param pattern The name of the pattern use when iterating over\n * @param index Where to start in the offset of the values array\n */\nfunction* PatternGenerator_PatternGenerator(values, pattern = "up", index = 0) {\n // safeguards\n assert(values.length > 0, "The array must have more than one value in it");\n switch (pattern) {\n case "up":\n yield* infiniteGen(values, upPatternGen);\n case "down":\n yield* infiniteGen(values, downPatternGen);\n case "upDown":\n yield* alternatingGenerator(values, true);\n case "downUp":\n yield* alternatingGenerator(values, false);\n case "alternateUp":\n yield* infiniteGen(values, jumpUp);\n case "alternateDown":\n yield* infiniteGen(values, jumpDown);\n case "random":\n yield* randomGen(values);\n case "randomOnce":\n yield* infiniteGen(values, randomOnce);\n case "randomWalk":\n yield* randomWalk(values);\n }\n}\n//# sourceMappingURL=PatternGenerator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Pattern.js\n\n\n\n\n/**\n * Pattern arpeggiates between the given notes\n * in a number of patterns.\n * @example\n * const pattern = new Tone.Pattern((time, note) => {\n * \t// the order of the notes passed in depends on the pattern\n * }, ["C2", "D4", "E5", "A6"], "upDown");\n * @category Event\n */\nclass Pattern extends (/* unused pure expression or super */ null && (Loop)) {\n constructor() {\n super(optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]));\n this.name = "Pattern";\n const options = optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]);\n this.callback = options.callback;\n this._values = options.values;\n this._pattern = PatternGenerator(options.values, options.pattern);\n this._type = options.pattern;\n }\n static getDefaults() {\n return Object.assign(Loop.getDefaults(), {\n pattern: "up",\n values: [],\n callback: noOp,\n });\n }\n /**\n * Internal function called when the notes should be called\n */\n _tick(time) {\n const value = this._pattern.next();\n this._value = value.value;\n this.callback(time, this._value);\n }\n /**\n * The array of events.\n */\n get values() {\n return this._values;\n }\n set values(val) {\n this._values = val;\n // reset the pattern\n this.pattern = this._type;\n }\n /**\n * The current value of the pattern.\n */\n get value() {\n return this._value;\n }\n /**\n * The pattern type. See Tone.CtrlPattern for the full list of patterns.\n */\n get pattern() {\n return this._type;\n }\n set pattern(pattern) {\n this._type = pattern;\n this._pattern = PatternGenerator(this._values, this._type);\n }\n}\n//# sourceMappingURL=Pattern.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Sequence.js\n\n\n\n\n\n/**\n * A sequence is an alternate notation of a part. Instead\n * of passing in an array of [time, event] pairs, pass\n * in an array of events which will be spaced at the\n * given subdivision. Sub-arrays will subdivide that beat\n * by the number of items are in the array.\n * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/)\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const seq = new Tone.Sequence((time, note) => {\n * \tsynth.triggerAttackRelease(note, 0.1, time);\n * \t// subdivisions are given as subarrays\n * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Sequence extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]));\n this.name = "Sequence";\n /**\n * The object responsible for scheduling all of the events\n */\n this._part = new Part({\n callback: this._seqCallback.bind(this),\n context: this.context,\n });\n /**\n * private reference to all of the sequence proxies\n */\n this._events = [];\n /**\n * The proxied array\n */\n this._eventsArray = [];\n const options = optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]);\n this._subdivision = this.toTicks(options.subdivision);\n this.events = options.events;\n // set all of the values\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.playbackRate = options.playbackRate;\n this.probability = options.probability;\n this.humanize = options.humanize;\n this.mute = options.mute;\n this.playbackRate = options.playbackRate;\n }\n static getDefaults() {\n return Object.assign(omitFromObject(ToneEvent.getDefaults(), ["value"]), {\n events: [],\n loop: true,\n loopEnd: 0,\n loopStart: 0,\n subdivision: "8n",\n });\n }\n /**\n * The internal callback for when an event is invoked\n */\n _seqCallback(time, value) {\n if (value !== null) {\n this.callback(time, value);\n }\n }\n /**\n * The sequence\n */\n get events() {\n return this._events;\n }\n set events(s) {\n this.clear();\n this._eventsArray = s;\n this._events = this._createSequence(this._eventsArray);\n this._eventsUpdated();\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset index to start at\n */\n start(time, offset) {\n this._part.start(time, offset ? this._indexTime(offset) : offset);\n return this;\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n this._part.stop(time);\n return this;\n }\n /**\n * The subdivision of the sequence. This can only be\n * set in the constructor. The subdivision is the\n * interval between successive steps.\n */\n get subdivision() {\n return new TicksClass(this.context, this._subdivision).toSeconds();\n }\n /**\n * Create a sequence proxy which can be monitored to create subsequences\n */\n _createSequence(array) {\n return new Proxy(array, {\n get: (target, property) => {\n // property is index in this case\n return target[property];\n },\n set: (target, property, value) => {\n if (isString(property) && isFinite(parseInt(property, 10))) {\n if (isArray(value)) {\n target[property] = this._createSequence(value);\n }\n else {\n target[property] = value;\n }\n }\n else {\n target[property] = value;\n }\n this._eventsUpdated();\n // return true to accept the changes\n return true;\n },\n });\n }\n /**\n * When the sequence has changed, all of the events need to be recreated\n */\n _eventsUpdated() {\n this._part.clear();\n this._rescheduleSequence(this._eventsArray, this._subdivision, this.startOffset);\n // update the loopEnd\n this.loopEnd = this.loopEnd;\n }\n /**\n * reschedule all of the events that need to be rescheduled\n */\n _rescheduleSequence(sequence, subdivision, startOffset) {\n sequence.forEach((value, index) => {\n const eventOffset = index * (subdivision) + startOffset;\n if (isArray(value)) {\n this._rescheduleSequence(value, subdivision / value.length, eventOffset);\n }\n else {\n const startTime = new TicksClass(this.context, eventOffset, "i").toSeconds();\n this._part.add(startTime, value);\n }\n });\n }\n /**\n * Get the time of the index given the Sequence\'s subdivision\n * @param index\n * @return The time of that index\n */\n _indexTime(index) {\n return new TicksClass(this.context, index * (this._subdivision) + this.startOffset).toSeconds();\n }\n /**\n * Clear all of the events\n */\n clear() {\n this._part.clear();\n return this;\n }\n dispose() {\n super.dispose();\n this._part.dispose();\n return this;\n }\n //-------------------------------------\n // PROXY CALLS\n //-------------------------------------\n get loop() {\n return this._part.loop;\n }\n set loop(l) {\n this._part.loop = l;\n }\n /**\n * The index at which the sequence should start looping\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(index) {\n this._loopStart = index;\n this._part.loopStart = this._indexTime(index);\n }\n /**\n * The index at which the sequence should end looping\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(index) {\n this._loopEnd = index;\n if (index === 0) {\n this._part.loopEnd = this._indexTime(this._eventsArray.length);\n }\n else {\n this._part.loopEnd = this._indexTime(index);\n }\n }\n get startOffset() {\n return this._part.startOffset;\n }\n set startOffset(start) {\n this._part.startOffset = start;\n }\n get playbackRate() {\n return this._part.playbackRate;\n }\n set playbackRate(rate) {\n this._part.playbackRate = rate;\n }\n get probability() {\n return this._part.probability;\n }\n set probability(prob) {\n this._part.probability = prob;\n }\n get progress() {\n return this._part.progress;\n }\n get humanize() {\n return this._part.humanize;\n }\n set humanize(variation) {\n this._part.humanize = variation;\n }\n /**\n * The number of scheduled events\n */\n get length() {\n return this._part.length;\n }\n}\n//# sourceMappingURL=Sequence.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/index.js\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/CrossFade.js\n\n\n\n\n\n\n/**\n * Tone.Crossfade provides equal power fading between two inputs.\n * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n * ```\n * +---------+\n * +> input a +>--+\n * +-----------+ +---------------------+ | | |\n * | 1s signal +>--\x3e stereoPannerNode L +>----\x3e gain | |\n * +-----------+ | | +---------+ |\n * +-> pan R +>-+ | +--------+\n * | +---------------------+ | +---\x3e output +>\n * +------+ | | +---------+ | +--------+\n * | fade +>----+ | +> input b +>--+\n * +------+ | | |\n * +--\x3e gain |\n * +---------+\n * ```\n * @example\n * const crossFade = new Tone.CrossFade().toDestination();\n * // connect two inputs Tone.to a/b\n * const inputA = new Tone.Oscillator(440, "square").connect(crossFade.a).start();\n * const inputB = new Tone.Oscillator(440, "sine").connect(crossFade.b).start();\n * // use the fade to control the mix between the two\n * crossFade.fade.value = 0.5;\n * @category Component\n */\nclass CrossFade_CrossFade extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"])));\n this.name = "CrossFade";\n /**\n * The crossfading is done by a StereoPannerNode\n */\n this._panner = this.context.createStereoPanner();\n /**\n * Split the output of the panner node into two values used to control the gains.\n */\n this._split = this.context.createChannelSplitter(2);\n /**\n * Convert the fade value into an audio range value so it can be connected\n * to the panner.pan AudioParam\n */\n this._g2a = new GainToAudio({ context: this.context });\n /**\n * The input which is at full level when fade = 0\n */\n this.a = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The input which is at full level when fade = 1\n */\n this.b = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output is a mix between `a` and `b` at the ratio of `fade`\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [this.a, this.b];\n const options = optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"]);\n this.fade = new Signal({\n context: this.context,\n units: "normalRange",\n value: options.fade,\n });\n readOnly(this, "fade");\n this.context.getConstant(1).connect(this._panner);\n this._panner.connect(this._split);\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = 1;\n this._panner.channelCountMode = "explicit";\n connect(this._split, this.a.gain, 0);\n connect(this._split, this.b.gain, 1);\n this.fade.chain(this._g2a, this._panner.pan);\n this.a.connect(this.output);\n this.b.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n fade: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.a.dispose();\n this.b.dispose();\n this.output.dispose();\n this.fade.dispose();\n this._g2a.dispose();\n this._panner.disconnect();\n this._split.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=CrossFade.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Effect.js\n\n\n\n\n/**\n * Effect is the base class for effects. Connect the effect between\n * the effectSend and effectReturn GainNodes, then control the amount of\n * effect which goes to the output using the wet control.\n */\nclass Effect_Effect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "Effect";\n /**\n * the drywet knob to control the amount of effect\n */\n this._dryWet = new CrossFade({ context: this.context });\n /**\n * The wet control is how much of the effected\n * will pass through to the output. 1 = 100% effected\n * signal, 0 = 100% dry signal.\n */\n this.wet = this._dryWet.fade;\n /**\n * connect the effectSend to the input of hte effect\n */\n this.effectSend = new Gain({ context: this.context });\n /**\n * connect the output of the effect to the effectReturn\n */\n this.effectReturn = new Gain({ context: this.context });\n /**\n * The effect input node\n */\n this.input = new Gain({ context: this.context });\n /**\n * The effect output\n */\n this.output = this._dryWet;\n // connections\n this.input.fan(this._dryWet.a, this.effectSend);\n this.effectReturn.connect(this._dryWet.b);\n this.wet.setValueAtTime(options.wet, 0);\n this._internalChannels = [this.effectReturn, this.effectSend];\n readOnly(this, "wet");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n /**\n * chains the effect in between the effectSend and effectReturn\n */\n connectEffect(effect) {\n // add it to the internal channels\n this._internalChannels.push(effect);\n this.effectSend.chain(effect, this.effectReturn);\n return this;\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this.effectSend.dispose();\n this.effectReturn.dispose();\n this.wet.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Effect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/LFOEffect.js\n\n\n\n/**\n * Base class for LFO-based effects.\n */\nclass LFOEffect_LFOEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "LFOEffect";\n this._lfo = new LFO({\n context: this.context,\n frequency: options.frequency,\n amplitude: options.depth,\n });\n this.depth = this._lfo.amplitude;\n this.frequency = this._lfo.frequency;\n this.type = options.type;\n readOnly(this, ["frequency", "depth"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 1,\n type: "sine",\n depth: 1,\n });\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfo.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfo.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfo.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfo.unsync();\n return this;\n }\n /**\n * The type of the LFO\'s oscillator: See [[Oscillator.type]]\n * @example\n * const autoFilter = new Tone.AutoFilter().start().toDestination();\n * const noise = new Tone.Noise().start().connect(autoFilter);\n * autoFilter.type = "square";\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFOEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoFilter.js\n\n\n\n/**\n * AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency.\n * Setting the LFO rate and depth allows for control over the filter modulation rate\n * and depth.\n *\n * @example\n * // create an autofilter and start it\'s LFO\n * const autoFilter = new Tone.AutoFilter("4n").toDestination().start();\n * // route an oscillator through the filter and start it\n * const oscillator = new Tone.Oscillator().connect(autoFilter).start();\n * @category Effect\n */\nclass AutoFilter extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]));\n this.name = "AutoFilter";\n const options = optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]);\n this.filter = new Filter(Object.assign(options.filter, {\n context: this.context,\n }));\n // connections\n this.connectEffect(this.filter);\n this._lfo.connect(this.filter.frequency);\n this.octaves = options.octaves;\n this.baseFrequency = options.baseFrequency;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n baseFrequency: 200,\n octaves: 2.6,\n filter: {\n type: "lowpass",\n rolloff: -12,\n Q: 1,\n }\n });\n }\n /**\n * The minimum value of the filter\'s cutoff frequency.\n */\n get baseFrequency() {\n return this._lfo.min;\n }\n set baseFrequency(freq) {\n this._lfo.min = this.toFrequency(freq);\n // and set the max\n this.octaves = this._octaves;\n }\n /**\n * The maximum value of the filter\'s cutoff frequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(oct) {\n this._octaves = oct;\n this._lfo.max = this._lfo.min * Math.pow(2, oct);\n }\n dispose() {\n super.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner.js\n\n\n\n\n/**\n * Panner is an equal power Left/Right Panner. It is a wrapper around the StereoPannerNode.\n * @example\n * return Tone.Offline(() => {\n * // move the input signal from right to left\n * \tconst panner = new Tone.Panner(1).toDestination();\n * \tpanner.pan.rampTo(-1, 0.5);\n * \tconst osc = new Tone.Oscillator(100).connect(panner).start();\n * }, 0.5, 2);\n * @category Component\n */\nclass Panner_Panner extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"])));\n this.name = "Panner";\n /**\n * the panner node\n */\n this._panner = this.context.createStereoPanner();\n this.input = this._panner;\n this.output = this._panner;\n const options = Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"]);\n this.pan = new Param_Param({\n context: this.context,\n param: this._panner.pan,\n value: options.pan,\n minValue: -1,\n maxValue: 1,\n });\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = options.channelCount;\n this._panner.channelCountMode = "explicit";\n // initial value\n Interface_readOnly(this, "pan");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n channelCount: 1,\n });\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.pan.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoPanner.js\n\n\n\n/**\n * AutoPanner is a [[Panner]] with an [[LFO]] connected to the pan amount.\n * [Related Reading](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/).\n *\n * @example\n * // create an autopanner and start it\n * const autoPanner = new Tone.AutoPanner("4n").toDestination().start();\n * // route an oscillator through the panner and start it\n * const oscillator = new Tone.Oscillator().connect(autoPanner).start();\n * @category Effect\n */\nclass AutoPanner extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]));\n this.name = "AutoPanner";\n const options = optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]);\n this._panner = new Panner({\n context: this.context,\n channelCount: options.channelCount\n });\n // connections\n this.connectEffect(this._panner);\n this._lfo.connect(this._panner.pan);\n this._lfo.min = -1;\n this._lfo.max = 1;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n channelCount: 1\n });\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoPanner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Follower.js\n\n\n\n\n/**\n * Follower is a simple envelope follower.\n * It\'s implemented by applying a lowpass filter to the absolute value of the incoming signal.\n * ```\n * +-----+ +---------------+\n * Input +--\x3e Abs +----\x3e OnePoleFilter +--\x3e Output\n * +-----+ +---------------+\n * ```\n * @category Component\n */\nclass Follower_Follower extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]));\n this.name = "Follower";\n const options = optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]);\n this._abs = this.input = new Abs({ context: this.context });\n this._lowpass = this.output = new OnePoleFilter({\n context: this.context,\n frequency: 1 / this.toSeconds(options.smoothing),\n type: "lowpass"\n });\n this._abs.connect(this._lowpass);\n this._smoothing = options.smoothing;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.05\n });\n }\n /**\n * The amount of time it takes a value change to arrive at the updated value.\n */\n get smoothing() {\n return this._smoothing;\n }\n set smoothing(smoothing) {\n this._smoothing = smoothing;\n this._lowpass.frequency = 1 / this.toSeconds(this.smoothing);\n }\n dispose() {\n super.dispose();\n this._abs.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Follower.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoWah.js\n\n\n\n\n\n\n\n\n/**\n * AutoWah connects a [[Follower]] to a [[Filter]].\n * The frequency of the filter, follows the input amplitude curve.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).\n *\n * @example\n * const autoWah = new Tone.AutoWah(50, 6, -30).toDestination();\n * // initialize the synth and connect to autowah\n * const synth = new Tone.Synth().connect(autoWah);\n * // Q value influences the effect of the wah - default is 2\n * autoWah.Q.value = 6;\n * // more audible on higher notes\n * synth.triggerAttackRelease("C4", "8n");\n * @category Effect\n */\nclass AutoWah extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]));\n this.name = "AutoWah";\n const options = optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.follower,\n });\n this._sweepRange = new ScaleExp({\n context: this.context,\n min: 0,\n max: 1,\n exponent: 0.5,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this._inputBoost = new Gain({ context: this.context });\n this._bandpass = new Filter({\n context: this.context,\n rolloff: -48,\n frequency: 0,\n Q: options.Q,\n });\n this._peaking = new Filter({\n context: this.context,\n type: "peaking"\n });\n this._peaking.gain.value = options.gain;\n this.gain = this._peaking.gain;\n this.Q = this._bandpass.Q;\n // the control signal path\n this.effectSend.chain(this._inputBoost, this._follower, this._sweepRange);\n this._sweepRange.connect(this._bandpass.frequency);\n this._sweepRange.connect(this._peaking.frequency);\n // the filtered path\n this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);\n // set the initial value\n this._setSweepRange();\n this.sensitivity = options.sensitivity;\n readOnly(this, ["gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n baseFrequency: 100,\n octaves: 6,\n sensitivity: 0,\n Q: 2,\n gain: 2,\n follower: 0.2,\n });\n }\n /**\n * The number of octaves that the filter will sweep above the baseFrequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._setSweepRange();\n }\n /**\n * The follower\'s smoothing time\n */\n get follower() {\n return this._follower.smoothing;\n }\n set follower(follower) {\n this._follower.smoothing = follower;\n }\n /**\n * The base frequency from which the sweep will start from.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(baseFreq) {\n this._baseFrequency = this.toFrequency(baseFreq);\n this._setSweepRange();\n }\n /**\n * The sensitivity to control how responsive to the input signal the filter is.\n */\n get sensitivity() {\n return gainToDb(1 / this._inputBoost.gain.value);\n }\n set sensitivity(sensitivity) {\n this._inputBoost.gain.value = 1 / dbToGain(sensitivity);\n }\n /**\n * sets the sweep range of the scaler\n */\n _setSweepRange() {\n this._sweepRange.min = this._baseFrequency;\n this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);\n }\n dispose() {\n super.dispose();\n this._follower.dispose();\n this._sweepRange.dispose();\n this._bandpass.dispose();\n this._peaking.dispose();\n this._inputBoost.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoWah.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.worklet.js\n\n\nconst BitCrusher_worklet_workletName = "bit-crusher";\nconst bitCrusherWorklet = /* javascript */ `\n\tclass BitCrusherWorklet extends SingleIOProcessor {\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "bits",\n\t\t\t\tdefaultValue: 12,\n\t\t\t\tminValue: 1,\n\t\t\t\tmaxValue: 16,\n\t\t\t\tautomationRate: \'k-rate\'\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, _channel, parameters) {\n\t\t\tconst step = Math.pow(0.5, parameters.bits - 1);\n\t\t\tconst val = step * Math.floor(input / step + 0.5);\n\t\t\treturn val;\n\t\t}\n\t}\n`;\nregisterProcessor(BitCrusher_worklet_workletName, bitCrusherWorklet);\n//# sourceMappingURL=BitCrusher.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.js\n\n\n\n\n\n\n\n/**\n * BitCrusher down-samples the incoming signal to a different bit depth.\n * Lowering the bit depth of the signal creates distortion. Read more about BitCrushing\n * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher).\n * @example\n * // initialize crusher and route a synth through it\n * const crusher = new Tone.BitCrusher(4).toDestination();\n * const synth = new Tone.Synth().connect(crusher);\n * synth.triggerAttackRelease("C2", 2);\n *\n * @category Effect\n */\nclass BitCrusher extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]));\n this.name = "BitCrusher";\n const options = optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]);\n this._bitCrusherWorklet = new BitCrusherWorklet({\n context: this.context,\n bits: options.bits,\n });\n // connect it up\n this.connectEffect(this._bitCrusherWorklet);\n this.bits = this._bitCrusherWorklet.bits;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n bits: 4,\n });\n }\n dispose() {\n super.dispose();\n this._bitCrusherWorklet.dispose();\n return this;\n }\n}\n/**\n * Internal class which creates an AudioWorklet to do the bit crushing\n */\nclass BitCrusherWorklet extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments));\n this.name = "BitCrusherWorklet";\n const options = optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.bits = new Param({\n context: this.context,\n value: options.bits,\n units: "positive",\n minValue: 1,\n maxValue: 16,\n param: this._dummyParam,\n swappable: true,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioWorklet.getDefaults(), {\n bits: 12,\n });\n }\n _audioWorkletName() {\n return workletName;\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const bits = node.parameters.get("bits");\n this.bits.setParam(bits);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.bits.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BitCrusher.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chebyshev.js\n\n\n\n/**\n * Chebyshev is a waveshaper which is good\n * for making different types of distortion sounds.\n * Note that odd orders sound very different from even ones,\n * and order = 1 is no change.\n * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).\n * @example\n * // create a new cheby\n * const cheby = new Tone.Chebyshev(50).toDestination();\n * // create a monosynth connected to our cheby\n * const synth = new Tone.MonoSynth().connect(cheby);\n * synth.triggerAttackRelease("C2", 0.4);\n * @category Effect\n */\nclass Chebyshev extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]));\n this.name = "Chebyshev";\n const options = optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096\n });\n this._order = options.order;\n this.connectEffect(this._shaper);\n this.order = options.order;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n order: 1,\n oversample: "none"\n });\n }\n /**\n * get the coefficient for that degree\n * @param x the x value\n * @param degree\n * @param memo memoize the computed value. this speeds up computation greatly.\n */\n _getCoefficient(x, degree, memo) {\n if (memo.has(degree)) {\n return memo.get(degree);\n }\n else if (degree === 0) {\n memo.set(degree, 0);\n }\n else if (degree === 1) {\n memo.set(degree, x);\n }\n else {\n memo.set(degree, 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo));\n }\n return memo.get(degree);\n }\n /**\n * The order of the Chebyshev polynomial which creates the equation which is applied to the incoming\n * signal through a Tone.WaveShaper. The equations are in the form:\n * ```\n * order 2: 2x^2 + 1\n * order 3: 4x^3 + 3x\n * ```\n * @min 1\n * @max 100\n */\n get order() {\n return this._order;\n }\n set order(order) {\n this._order = order;\n this._shaper.setMap((x => {\n return this._getCoefficient(x, order, new Map());\n }));\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chebyshev.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Split.js\n\n\n/**\n * Split splits an incoming signal into the number of given channels.\n *\n * @example\n * const split = new Tone.Split();\n * // stereoSignal.connect(split);\n * @category Component\n */\nclass Split_Split extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]));\n this.name = "Split";\n const options = optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]);\n this._splitter = this.input = this.output = this.context.createChannelSplitter(options.channels);\n this._internalChannels = [this._splitter];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._splitter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Split.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Merge.js\n\n\n/**\n * Merge brings multiple mono input channels into a single multichannel output channel.\n *\n * @example\n * const merge = new Tone.Merge().toDestination();\n * // routing a sine tone in the left channel\n * const osc = new Tone.Oscillator().connect(merge, 0, 0).start();\n * // and noise in the right channel\n * const noise = new Tone.Noise().connect(merge, 0, 1).start();;\n * @category Component\n */\nclass Merge_Merge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]));\n this.name = "Merge";\n const options = optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]);\n this._merger = this.output = this.input = this.context.createChannelMerger(options.channels);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._merger.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Merge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoEffect.js\n\n\n\n\n\n\n/**\n * Base class for Stereo effects.\n */\nclass StereoEffect_StereoEffect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "StereoEffect";\n this.input = new Gain({ context: this.context });\n // force mono sources to be stereo\n this.input.channelCount = 2;\n this.input.channelCountMode = "explicit";\n this._dryWet = this.output = new CrossFade({\n context: this.context,\n fade: options.wet\n });\n this.wet = this._dryWet.fade;\n this._split = new Split({ context: this.context, channels: 2 });\n this._merge = new Merge({ context: this.context, channels: 2 });\n // connections\n this.input.connect(this._split);\n // dry wet connections\n this.input.connect(this._dryWet.a);\n this._merge.connect(this._dryWet.b);\n readOnly(this, ["wet"]);\n }\n /**\n * Connect the left part of the effect\n */\n connectEffectLeft(...nodes) {\n this._split.connect(nodes[0], 0, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 0);\n }\n /**\n * Connect the right part of the effect\n */\n connectEffectRight(...nodes) {\n this._split.connect(nodes[0], 1, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 1);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this._split.dispose();\n this._merge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoFeedbackEffect.js\n\n\n\n\n\n\n/**\n * Base class for stereo feedback effects where the effectReturn is fed back into the same channel.\n */\nclass StereoFeedbackEffect_StereoFeedbackEffect extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor(options) {\n super(options);\n this.feedback = new Signal({\n context: this.context,\n value: options.feedback,\n units: "normalRange"\n });\n this._feedbackL = new Gain({ context: this.context });\n this._feedbackR = new Gain({ context: this.context });\n this._feedbackSplit = new Split({ context: this.context, channels: 2 });\n this._feedbackMerge = new Merge({ context: this.context, channels: 2 });\n this._merge.connect(this._feedbackSplit);\n this._feedbackMerge.connect(this._split);\n // the left output connected to the left input\n this._feedbackSplit.connect(this._feedbackL, 0, 0);\n this._feedbackL.connect(this._feedbackMerge, 0, 0);\n // the right output connected to the right input\n this._feedbackSplit.connect(this._feedbackR, 1, 0);\n this._feedbackR.connect(this._feedbackMerge, 0, 1);\n // the feedback control\n this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);\n readOnly(this, ["feedback"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n feedback: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.feedback.dispose();\n this._feedbackL.dispose();\n this._feedbackR.dispose();\n this._feedbackSplit.dispose();\n this._feedbackMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chorus.js\n\n\n\n\n\n/**\n * Chorus is a stereo chorus effect composed of a left and right delay with an [[LFO]] applied to the delayTime of each channel.\n * When [[feedback]] is set to a value larger than 0, you also get Flanger-type effects.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).\n * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).\n *\n * @example\n * const chorus = new Tone.Chorus(4, 2.5, 0.5).toDestination().start();\n * const synth = new Tone.PolySynth().connect(chorus);\n * synth.triggerAttackRelease(["C3", "E3", "G3"], "8n");\n *\n * @category Effect\n */\nclass Chorus extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]));\n this.name = "Chorus";\n const options = optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]);\n this._depth = options.depth;\n this._delayTime = options.delayTime / 1000;\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180\n });\n this._delayNodeL = new Delay({ context: this.context });\n this._delayNodeR = new Delay({ context: this.context });\n this.frequency = this._lfoL.frequency;\n readOnly(this, ["frequency"]);\n // have one LFO frequency control the other\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // connections\n this.connectEffectLeft(this._delayNodeL);\n this.connectEffectRight(this._delayNodeR);\n // lfo setup\n this._lfoL.connect(this._delayNodeL.delayTime);\n this._lfoR.connect(this._delayNodeR.delayTime);\n // set the initial values\n this.depth = this._depth;\n this.type = options.type;\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoFeedbackEffect.getDefaults(), {\n frequency: 1.5,\n delayTime: 3.5,\n depth: 0.7,\n type: "sine",\n spread: 180,\n feedback: 0,\n wet: 0.5,\n });\n }\n /**\n * The depth of the effect. A depth of 1 makes the delayTime\n * modulate between 0 and 2*delayTime (centered around the delayTime).\n */\n get depth() {\n return this._depth;\n }\n set depth(depth) {\n this._depth = depth;\n const deviation = this._delayTime * depth;\n this._lfoL.min = Math.max(this._delayTime - deviation, 0);\n this._lfoL.max = this._delayTime + deviation;\n this._lfoR.min = Math.max(this._delayTime - deviation, 0);\n this._lfoR.max = this._delayTime + deviation;\n }\n /**\n * The delayTime in milliseconds of the chorus. A larger delayTime\n * will give a more pronounced effect. Nominal range a delayTime\n * is between 2 and 20ms.\n */\n get delayTime() {\n return this._delayTime * 1000;\n }\n set delayTime(delayTime) {\n this._delayTime = delayTime / 1000;\n this.depth = this._depth;\n }\n /**\n * The oscillator type of the LFO.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase;\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n return this;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._delayNodeL.dispose();\n this._delayNodeR.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chorus.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Distortion.js\n\n\n\n/**\n * A simple distortion effect using Tone.WaveShaper.\n * Algorithm from [this stackoverflow answer](http://stackoverflow.com/a/22313408).\n *\n * @example\n * const dist = new Tone.Distortion(0.8).toDestination();\n * const fm = new Tone.FMSynth().connect(dist);\n * fm.triggerAttackRelease("A1", "8n");\n * @category Effect\n */\nclass Distortion extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]));\n this.name = "Distortion";\n const options = optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096,\n });\n this._distortion = options.distortion;\n this.connectEffect(this._shaper);\n this.distortion = options.distortion;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n distortion: 0.4,\n oversample: "none",\n });\n }\n /**\n * The amount of distortion. Nominal range is between 0 and 1.\n */\n get distortion() {\n return this._distortion;\n }\n set distortion(amount) {\n this._distortion = amount;\n const k = amount * 100;\n const deg = Math.PI / 180;\n this._shaper.setMap((x) => {\n if (Math.abs(x) < 0.001) {\n // should output 0 when input is 0\n return 0;\n }\n else {\n return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));\n }\n });\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Distortion.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackEffect.js\n\n\n\n/**\n * FeedbackEffect provides a loop between an audio source and its own output.\n * This is a base-class for feedback effects.\n */\nclass FeedbackEffect_FeedbackEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "FeedbackEffect";\n this._feedbackGain = new Gain({\n context: this.context,\n gain: options.feedback,\n units: "normalRange",\n });\n this.feedback = this._feedbackGain.gain;\n readOnly(this, "feedback");\n // the feedback loop\n this.effectReturn.chain(this._feedbackGain, this.effectSend);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n feedback: 0.125,\n });\n }\n dispose() {\n super.dispose();\n this._feedbackGain.dispose();\n this.feedback.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackDelay.js\n\n\n\n\n/**\n * FeedbackDelay is a DelayNode in which part of output signal is fed back into the delay.\n *\n * @param delayTime The delay applied to the incoming signal.\n * @param feedback The amount of the effected signal which is fed back through the delay.\n * @example\n * const feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toDestination();\n * const tom = new Tone.MembraneSynth({\n * \toctaves: 4,\n * \tpitchDecay: 0.1\n * }).connect(feedbackDelay);\n * tom.triggerAttackRelease("A2", "32n");\n * @category Effect\n */\nclass FeedbackDelay extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "FeedbackDelay";\n const options = optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: options.delayTime,\n maxDelay: options.maxDelay,\n });\n this.delayTime = this._delayNode.delayTime;\n // connect it up\n this.connectEffect(this._delayNode);\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1,\n });\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/PhaseShiftAllpass.js\n\n\n/**\n * PhaseShiftAllpass is an very efficient implementation of a Hilbert Transform\n * using two Allpass filter banks whose outputs have a phase difference of 90°.\n * Here the `offset90` phase is offset by +90° in relation to `output`.\n * Coefficients and structure was developed by Olli Niemitalo.\n * For more details see: http://yehar.com/blog/?p=368\n * @category Component\n */\nclass PhaseShiftAllpass_PhaseShiftAllpass extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "PhaseShiftAllpass";\n this.input = new Gain({ context: this.context });\n /**\n * The phase shifted output\n */\n this.output = new Gain({ context: this.context });\n /**\n * The PhaseShifted allpass output\n */\n this.offset90 = new Gain({ context: this.context });\n const allpassBank1Values = [0.6923878, 0.9360654322959, 0.9882295226860, 0.9987488452737];\n const allpassBank2Values = [0.4021921162426, 0.8561710882420, 0.9722909545651, 0.9952884791278];\n this._bank0 = this._createAllPassFilterBank(allpassBank1Values);\n this._bank1 = this._createAllPassFilterBank(allpassBank2Values);\n this._oneSampleDelay = this.context.createIIRFilter([0.0, 1.0], [1.0, 0.0]);\n // connect Allpass filter banks\n connectSeries(this.input, ...this._bank0, this._oneSampleDelay, this.output);\n connectSeries(this.input, ...this._bank1, this.offset90);\n }\n /**\n * Create all of the IIR filters from an array of values using the coefficient calculation.\n */\n _createAllPassFilterBank(bankValues) {\n const nodes = bankValues.map(value => {\n const coefficients = [[value * value, 0, -1], [1, 0, -(value * value)]];\n return this.context.createIIRFilter(coefficients[0], coefficients[1]);\n });\n return nodes;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.offset90.dispose();\n this._bank0.forEach(f => f.disconnect());\n this._bank1.forEach(f => f.disconnect());\n this._oneSampleDelay.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=PhaseShiftAllpass.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FrequencyShifter.js\n\n\n\n\n\n\n\n\n\n/**\n * FrequencyShifter can be used to shift all frequencies of a signal by a fixed amount.\n * The amount can be changed at audio rate and the effect is applied in real time.\n * The frequency shifting is implemented with a technique called single side band modulation using a ring modulator.\n * Note: Contrary to pitch shifting, all frequencies are shifted by the same amount,\n * destroying the harmonic relationship between them. This leads to the classic ring modulator timbre distortion.\n * The algorithm will produces some aliasing towards the high end, especially if your source material\n * contains a lot of high frequencies. Unfortunatelly the webaudio API does not support resampling\n * buffers in real time, so it is not possible to fix it properly. Depending on the use case it might\n * be an option to low pass filter your input before frequency shifting it to get ride of the aliasing.\n * You can find a very detailed description of the algorithm here: https://larzeitlin.github.io/RMFS/\n *\n * @example\n * const input = new Tone.Oscillator(230, "sawtooth").start();\n * const shift = new Tone.FrequencyShifter(42).toDestination();\n * input.connect(shift);\n * @category Effect\n */\nclass FrequencyShifter extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]));\n this.name = "FrequencyShifter";\n const options = optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]);\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n minValue: -this.context.sampleRate / 2,\n maxValue: this.context.sampleRate / 2,\n });\n this._sine = new ToneOscillatorNode({\n context: this.context,\n type: "sine",\n });\n this._cosine = new Oscillator({\n context: this.context,\n phase: -90,\n type: "sine",\n });\n this._sineMultiply = new Multiply({ context: this.context });\n this._cosineMultiply = new Multiply({ context: this.context });\n this._negate = new Negate({ context: this.context });\n this._add = new Add({ context: this.context });\n this._phaseShifter = new PhaseShiftAllpass({ context: this.context });\n this.effectSend.connect(this._phaseShifter);\n // connect the carrier frequency signal to the two oscillators\n this.frequency.fan(this._sine.frequency, this._cosine.frequency);\n this._phaseShifter.offset90.connect(this._cosineMultiply);\n this._cosine.connect(this._cosineMultiply.factor);\n this._phaseShifter.connect(this._sineMultiply);\n this._sine.connect(this._sineMultiply.factor);\n this._sineMultiply.connect(this._negate);\n this._cosineMultiply.connect(this._add);\n this._negate.connect(this._add.addend);\n this._add.connect(this.effectReturn);\n // start the oscillators at the same time\n const now = this.immediate();\n this._sine.start(now);\n this._cosine.start(now);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 0,\n });\n }\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this._add.dispose();\n this._cosine.dispose();\n this._cosineMultiply.dispose();\n this._negate.dispose();\n this._phaseShifter.dispose();\n this._sine.dispose();\n this._sineMultiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyShifter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Freeverb.js\n\n\n\n\n\n/**\n * An array of comb filter delay values from Freeverb implementation\n */\nconst combFilterTunings = (/* unused pure expression or super */ null && ([1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100]));\n/**\n * An array of allpass filter frequency values from Freeverb implementation\n */\nconst allpassFilterFrequencies = (/* unused pure expression or super */ null && ([225, 556, 441, 341]));\n/**\n * Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html).\n * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp).\n * Freeverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const freeverb = new Tone.Freeverb().toDestination();\n * freeverb.dampening = 1000;\n * // routing synth through the reverb\n * const synth = new Tone.NoiseSynth().connect(freeverb);\n * synth.triggerAttackRelease(0.05);\n * @category Effect\n */\nclass Freeverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]));\n this.name = "Freeverb";\n /**\n * the comb filters\n */\n this._combFilters = [];\n /**\n * the allpass filters on the left\n */\n this._allpassFiltersL = [];\n /**\n * the allpass filters on the right\n */\n this._allpassFiltersR = [];\n const options = optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n // make the allpass filters on the right\n this._allpassFiltersL = allpassFilterFrequencies.map(freq => {\n const allpassL = this.context.createBiquadFilter();\n allpassL.type = "allpass";\n allpassL.frequency.value = freq;\n return allpassL;\n });\n // make the allpass filters on the left\n this._allpassFiltersR = allpassFilterFrequencies.map(freq => {\n const allpassR = this.context.createBiquadFilter();\n allpassR.type = "allpass";\n allpassR.frequency.value = freq;\n return allpassR;\n });\n // make the comb filters\n this._combFilters = combFilterTunings.map((delayTime, index) => {\n const lfpf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n delayTime,\n });\n if (index < combFilterTunings.length / 2) {\n this.connectEffectLeft(lfpf, ...this._allpassFiltersL);\n }\n else {\n this.connectEffectRight(lfpf, ...this._allpassFiltersR);\n }\n this.roomSize.connect(lfpf.resonance);\n return lfpf;\n });\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.7,\n dampening: 3000\n });\n }\n /**\n * The amount of dampening of the reverberant signal.\n */\n get dampening() {\n return this._combFilters[0].dampening;\n }\n set dampening(d) {\n this._combFilters.forEach(c => c.dampening = d);\n }\n dispose() {\n super.dispose();\n this._allpassFiltersL.forEach(al => al.disconnect());\n this._allpassFiltersR.forEach(ar => ar.disconnect());\n this._combFilters.forEach(cf => cf.dispose());\n this.roomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Freeverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/JCReverb.js\n\n\n\n\n\n\n/**\n * an array of the comb filter delay time values\n */\nconst combFilterDelayTimes = (/* unused pure expression or super */ null && ([1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000]));\n/**\n * the resonances of each of the comb filters\n */\nconst combFilterResonances = (/* unused pure expression or super */ null && ([0.773, 0.802, 0.753, 0.733]));\n/**\n * the allpass filter frequencies\n */\nconst allpassFilterFreqs = (/* unused pure expression or super */ null && ([347, 113, 37]));\n/**\n * JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html)\n * tuned by John Chowning in 1970.\n * It is made up of three allpass filters and four [[FeedbackCombFilter]].\n * JCReverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const reverb = new Tone.JCReverb(0.4).toDestination();\n * const delay = new Tone.FeedbackDelay(0.5);\n * // connecting the synth to reverb through delay\n * const synth = new Tone.DuoSynth().chain(delay, reverb);\n * synth.triggerAttackRelease("A4", "8n");\n *\n * @category Effect\n */\nclass JCReverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]));\n this.name = "JCReverb";\n /**\n * a series of allpass filters\n */\n this._allpassFilters = [];\n /**\n * parallel feedback comb filters\n */\n this._feedbackCombFilters = [];\n const options = optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n this._scaleRoomSize = new Scale({\n context: this.context,\n min: -0.733,\n max: 0.197,\n });\n // make the allpass filters\n this._allpassFilters = allpassFilterFreqs.map(freq => {\n const allpass = this.context.createBiquadFilter();\n allpass.type = "allpass";\n allpass.frequency.value = freq;\n return allpass;\n });\n // and the comb filters\n this._feedbackCombFilters = combFilterDelayTimes.map((delayTime, index) => {\n const fbcf = new FeedbackCombFilter({\n context: this.context,\n delayTime,\n });\n this._scaleRoomSize.connect(fbcf.resonance);\n fbcf.resonance.value = combFilterResonances[index];\n if (index < combFilterDelayTimes.length / 2) {\n this.connectEffectLeft(...this._allpassFilters, fbcf);\n }\n else {\n this.connectEffectRight(...this._allpassFilters, fbcf);\n }\n return fbcf;\n });\n // chain the allpass filters together\n this.roomSize.connect(this._scaleRoomSize);\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this._allpassFilters.forEach(apf => apf.disconnect());\n this._feedbackCombFilters.forEach(fbcf => fbcf.dispose());\n this.roomSize.dispose();\n this._scaleRoomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=JCReverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoXFeedbackEffect.js\n\n\n/**\n * Just like a [[StereoFeedbackEffect]], but the feedback is routed from left to right\n * and right to left instead of on the same channel.\n * ```\n * +--------------------------------+ feedbackL <-----------------------------------+\n * | |\n * +--\x3e +-----\x3e +----\x3e +-----+\n * feedbackMerge +--\x3e split (EFFECT) merge +--\x3e feedbackSplit | |\n * +--\x3e +-----\x3e +----\x3e +---+ |\n * | |\n * +--------------------------------+ feedbackR <-------------------------------------+\n * ```\n */\nclass StereoXFeedbackEffect_StereoXFeedbackEffect extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor(options) {\n super(options);\n // the left output connected to the right input\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._feedbackMerge, 0, 1);\n // the left output connected to the right input\n this._feedbackR.disconnect();\n this._feedbackR.connect(this._feedbackMerge, 0, 0);\n readOnly(this, ["feedback"]);\n }\n}\n//# sourceMappingURL=StereoXFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PingPongDelay.js\n\n\n\n\n\n/**\n * PingPongDelay is a feedback delay effect where the echo is heard\n * first in one channel and next in the opposite channel. In a stereo\n * system these are the right and left channels.\n * PingPongDelay in more simplified terms is two Tone.FeedbackDelays\n * with independent delay values. Each delay is routed to one channel\n * (left or right), and the channel triggered second will always\n * trigger at the same interval after the first.\n * @example\n * const pingPong = new Tone.PingPongDelay("4n", 0.2).toDestination();\n * const drum = new Tone.MembraneSynth().connect(pingPong);\n * drum.triggerAttackRelease("C4", "32n");\n * @category Effect\n */\nclass PingPongDelay extends (/* unused pure expression or super */ null && (StereoXFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "PingPongDelay";\n const options = optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._leftDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay,\n });\n this._rightDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this._rightPreDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this.delayTime = new Signal({\n context: this.context,\n units: "time",\n value: options.delayTime,\n });\n // connect it up\n this.connectEffectLeft(this._leftDelay);\n this.connectEffectRight(this._rightPreDelay, this._rightDelay);\n this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);\n // rearranged the feedback to be after the rightPreDelay\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._rightDelay);\n readOnly(this, ["delayTime"]);\n }\n static getDefaults() {\n return Object.assign(StereoXFeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1\n });\n }\n dispose() {\n super.dispose();\n this._leftDelay.dispose();\n this._rightDelay.dispose();\n this._rightPreDelay.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PingPongDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PitchShift.js\n\n\n\n\n\n\n\n\n/**\n * PitchShift does near-realtime pitch shifting to the incoming signal.\n * The effect is achieved by speeding up or slowing down the delayTime\n * of a DelayNode using a sawtooth wave.\n * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf).\n * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html).\n * @category Effect\n */\nclass PitchShift extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]));\n this.name = "PitchShift";\n const options = optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]);\n this._frequency = new Signal({ context: this.context });\n this._delayA = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoA = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth"\n }).connect(this._delayA.delayTime);\n this._delayB = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoB = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth",\n phase: 180\n }).connect(this._delayB.delayTime);\n this._crossFade = new CrossFade({ context: this.context });\n this._crossFadeLFO = new LFO({\n context: this.context,\n min: 0,\n max: 1,\n type: "triangle",\n phase: 90\n }).connect(this._crossFade.fade);\n this._feedbackDelay = new Delay({\n delayTime: options.delayTime,\n context: this.context,\n });\n this.delayTime = this._feedbackDelay.delayTime;\n readOnly(this, "delayTime");\n this._pitch = options.pitch;\n this._windowSize = options.windowSize;\n // connect the two delay lines up\n this._delayA.connect(this._crossFade.a);\n this._delayB.connect(this._crossFade.b);\n // connect the frequency\n this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency);\n // route the input\n this.effectSend.fan(this._delayA, this._delayB);\n this._crossFade.chain(this._feedbackDelay, this.effectReturn);\n // start the LFOs at the same time\n const now = this.now();\n this._lfoA.start(now);\n this._lfoB.start(now);\n this._crossFadeLFO.start(now);\n // set the initial value\n this.windowSize = this._windowSize;\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n pitch: 0,\n windowSize: 0.1,\n delayTime: 0,\n feedback: 0\n });\n }\n /**\n * Repitch the incoming signal by some interval (measured in semi-tones).\n * @example\n * const pitchShift = new Tone.PitchShift().toDestination();\n * const osc = new Tone.Oscillator().connect(pitchShift).start().toDestination();\n * pitchShift.pitch = -12; // down one octave\n * pitchShift.pitch = 7; // up a fifth\n */\n get pitch() {\n return this._pitch;\n }\n set pitch(interval) {\n this._pitch = interval;\n let factor = 0;\n if (interval < 0) {\n this._lfoA.min = 0;\n this._lfoA.max = this._windowSize;\n this._lfoB.min = 0;\n this._lfoB.max = this._windowSize;\n factor = intervalToFrequencyRatio(interval - 1) + 1;\n }\n else {\n this._lfoA.min = this._windowSize;\n this._lfoA.max = 0;\n this._lfoB.min = this._windowSize;\n this._lfoB.max = 0;\n factor = intervalToFrequencyRatio(interval) - 1;\n }\n this._frequency.value = factor * (1.2 / this._windowSize);\n }\n /**\n * The window size corresponds roughly to the sample length in a looping sampler.\n * Smaller values are desirable for a less noticeable delay time of the pitch shifted\n * signal, but larger values will result in smoother pitch shifting for larger intervals.\n * A nominal range of 0.03 to 0.1 is recommended.\n */\n get windowSize() {\n return this._windowSize;\n }\n set windowSize(size) {\n this._windowSize = this.toSeconds(size);\n this.pitch = this._pitch;\n }\n dispose() {\n super.dispose();\n this._frequency.dispose();\n this._delayA.dispose();\n this._delayB.dispose();\n this._lfoA.dispose();\n this._lfoB.dispose();\n this._crossFade.dispose();\n this._crossFadeLFO.dispose();\n this._feedbackDelay.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PitchShift.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Phaser.js\n\n\n\n\n\n/**\n * Phaser is a phaser effect. Phasers work by changing the phase\n * of different frequency components of an incoming signal. Read more on\n * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).\n * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).\n * @example\n * const phaser = new Tone.Phaser({\n * \tfrequency: 15,\n * \toctaves: 5,\n * \tbaseFrequency: 1000\n * }).toDestination();\n * const synth = new Tone.FMSynth().connect(phaser);\n * synth.triggerAttackRelease("E3", "2n");\n * @category Effect\n */\nclass Phaser extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]));\n this.name = "Phaser";\n const options = optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]);\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this.Q = new Signal({\n context: this.context,\n value: options.Q,\n units: "positive",\n });\n this._filtersL = this._makeFilters(options.stages, this._lfoL);\n this._filtersR = this._makeFilters(options.stages, this._lfoR);\n this.frequency = this._lfoL.frequency;\n this.frequency.value = options.frequency;\n // connect them up\n this.connectEffectLeft(...this._filtersL);\n this.connectEffectRight(...this._filtersR);\n // control the frequency with one LFO\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // set the options\n this.baseFrequency = options.baseFrequency;\n this.octaves = options.octaves;\n // start the lfo\n this._lfoL.start();\n this._lfoR.start();\n readOnly(this, ["frequency", "Q"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 0.5,\n octaves: 3,\n stages: 10,\n Q: 10,\n baseFrequency: 350,\n });\n }\n _makeFilters(stages, connectToFreq) {\n const filters = [];\n // make all the filters\n for (let i = 0; i < stages; i++) {\n const filter = this.context.createBiquadFilter();\n filter.type = "allpass";\n this.Q.connect(filter.Q);\n connectToFreq.connect(filter.frequency);\n filters.push(filter);\n }\n return filters;\n }\n /**\n * The number of octaves the phase goes above the baseFrequency\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n const max = this._baseFrequency * Math.pow(2, octaves);\n this._lfoL.max = max;\n this._lfoR.max = max;\n }\n /**\n * The the base frequency of the filters.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(freq) {\n this._baseFrequency = this.toFrequency(freq);\n this._lfoL.min = this._baseFrequency;\n this._lfoR.min = this._baseFrequency;\n this.octaves = this._octaves;\n }\n dispose() {\n super.dispose();\n this.Q.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._filtersL.forEach(f => f.disconnect());\n this._filtersR.forEach(f => f.disconnect());\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Phaser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Reverb.js\n\n\n\n\n\n\n\n\n\n/**\n * Simple convolution created with decaying noise.\n * Generates an Impulse Response Buffer\n * with Tone.Offline then feeds the IR into ConvolverNode.\n * The impulse response generation is async, so you have\n * to wait until [[ready]] resolves before it will make a sound.\n *\n * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen).\n * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License.\n *\n * @category Effect\n */\nclass Reverb extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]));\n this.name = "Reverb";\n /**\n * Convolver node\n */\n this._convolver = this.context.createConvolver();\n /**\n * Resolves when the reverb buffer is generated. Whenever either [[decay]]\n * or [[preDelay]] are set, you have to wait until [[ready]] resolves\n * before the IR is generated with the latest values.\n */\n this.ready = Promise.resolve();\n const options = optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]);\n this._decay = options.decay;\n this._preDelay = options.preDelay;\n this.generate();\n this.connectEffect(this._convolver);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n decay: 1.5,\n preDelay: 0.01,\n });\n }\n /**\n * The duration of the reverb.\n */\n get decay() {\n return this._decay;\n }\n set decay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0.001);\n this._decay = time;\n this.generate();\n }\n /**\n * The amount of time before the reverb is fully ramped in.\n */\n get preDelay() {\n return this._preDelay;\n }\n set preDelay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0);\n this._preDelay = time;\n this.generate();\n }\n /**\n * Generate the Impulse Response. Returns a promise while the IR is being generated.\n * @return Promise which returns this object.\n */\n generate() {\n return __awaiter(this, void 0, void 0, function* () {\n const previousReady = this.ready;\n // create a noise burst which decays over the duration in each channel\n const context = new OfflineContext(2, this._decay + this._preDelay, this.context.sampleRate);\n const noiseL = new Noise({ context });\n const noiseR = new Noise({ context });\n const merge = new Merge({ context });\n noiseL.connect(merge, 0, 0);\n noiseR.connect(merge, 0, 1);\n const gainNode = new Gain({ context }).toDestination();\n merge.connect(gainNode);\n noiseL.start(0);\n noiseR.start(0);\n // predelay\n gainNode.gain.setValueAtTime(0, 0);\n gainNode.gain.setValueAtTime(1, this._preDelay);\n // decay\n gainNode.gain.exponentialApproachValueAtTime(0, this._preDelay, this.decay);\n // render the buffer\n const renderPromise = context.render();\n this.ready = renderPromise.then(noOp);\n // wait for the previous `ready` to resolve\n yield previousReady;\n // set the buffer\n this._convolver.buffer = (yield renderPromise).get();\n return this;\n });\n }\n dispose() {\n super.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Reverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideSplit.js\n\n\n\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels).\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideSplit_MidSideSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideSplit_MidSideSplit.getDefaults(), arguments));\n this.name = "MidSideSplit";\n this._split = this.input = new Split({\n channels: 2,\n context: this.context\n });\n this._midAdd = new Add({ context: this.context });\n this.mid = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._sideSubtract = new Subtract({ context: this.context });\n this.side = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._split.connect(this._midAdd, 0);\n this._split.connect(this._midAdd.addend, 1);\n this._split.connect(this._sideSubtract, 0);\n this._split.connect(this._sideSubtract.subtrahend, 1);\n this._midAdd.connect(this.mid);\n this._sideSubtract.connect(this.side);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midAdd.dispose();\n this._sideSubtract.dispose();\n this._split.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideMerge.js\n\n\n\n\n\n\n\n/**\n * MidSideMerge merges the mid and side signal after they\'ve been separated by [[MidSideSplit]]\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideMerge_MidSideMerge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideMerge_MidSideMerge.getDefaults(), arguments));\n this.name = "MidSideMerge";\n this.mid = new Gain({ context: this.context });\n this.side = new Gain({ context: this.context });\n this._left = new Add({ context: this.context });\n this._leftMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._right = new Subtract({ context: this.context });\n this._rightMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._merge = this.output = new Merge({ context: this.context });\n this.mid.fan(this._left);\n this.side.connect(this._left.addend);\n this.mid.connect(this._right);\n this.side.connect(this._right.subtrahend);\n this._left.connect(this._leftMult);\n this._right.connect(this._rightMult);\n this._leftMult.connect(this._merge, 0, 0);\n this._rightMult.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._leftMult.dispose();\n this._rightMult.dispose();\n this._left.dispose();\n this._right.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideMerge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/MidSideEffect.js\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal\n * (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels)\n * and effects them separately before being recombined.\n * Applies a Mid/Side seperation and recombination.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * This is a base-class for Mid/Side Effects.\n * @category Effect\n */\nclass MidSideEffect_MidSideEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "MidSideEffect";\n this._midSideMerge = new MidSideMerge({ context: this.context });\n this._midSideSplit = new MidSideSplit({ context: this.context });\n this._midSend = this._midSideSplit.mid;\n this._sideSend = this._midSideSplit.side;\n this._midReturn = this._midSideMerge.mid;\n this._sideReturn = this._midSideMerge.side;\n // the connections\n this.effectSend.connect(this._midSideSplit);\n this._midSideMerge.connect(this.effectReturn);\n }\n /**\n * Connect the mid chain of the effect\n */\n connectEffectMid(...nodes) {\n this._midSend.chain(...nodes, this._midReturn);\n }\n /**\n * Connect the side chain of the effect\n */\n connectEffectSide(...nodes) {\n this._sideSend.chain(...nodes, this._sideReturn);\n }\n dispose() {\n super.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n this._midSend.dispose();\n this._sideSend.dispose();\n this._midReturn.dispose();\n this._sideReturn.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoWidener.js\n\n\n\n\n\n\n\n/**\n * Applies a width factor to the mid/side seperation.\n * 0 is all mid and 1 is all side.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * ```\n * Mid *= 2*(1-width)<br>\n * Side *= 2*width\n * ```\n * @category Effect\n */\nclass StereoWidener extends (/* unused pure expression or super */ null && (MidSideEffect)) {\n constructor() {\n super(optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]));\n this.name = "StereoWidener";\n const options = optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]);\n this.width = new Signal({\n context: this.context,\n value: options.width,\n units: "normalRange",\n });\n readOnly(this, ["width"]);\n this._twoTimesWidthMid = new Multiply({\n context: this.context,\n value: 2,\n });\n this._twoTimesWidthSide = new Multiply({\n context: this.context,\n value: 2,\n });\n this._midMult = new Multiply({ context: this.context });\n this._twoTimesWidthMid.connect(this._midMult.factor);\n this.connectEffectMid(this._midMult);\n this._oneMinusWidth = new Subtract({ context: this.context });\n this._oneMinusWidth.connect(this._twoTimesWidthMid);\n connect(this.context.getConstant(1), this._oneMinusWidth);\n this.width.connect(this._oneMinusWidth.subtrahend);\n this._sideMult = new Multiply({ context: this.context });\n this.width.connect(this._twoTimesWidthSide);\n this._twoTimesWidthSide.connect(this._sideMult.factor);\n this.connectEffectSide(this._sideMult);\n }\n static getDefaults() {\n return Object.assign(MidSideEffect.getDefaults(), {\n width: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.width.dispose();\n this._midMult.dispose();\n this._sideMult.dispose();\n this._twoTimesWidthMid.dispose();\n this._twoTimesWidthSide.dispose();\n this._oneMinusWidth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoWidener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Tremolo.js\n\n\n\n\n\n\n/**\n * Tremolo modulates the amplitude of an incoming signal using an [[LFO]].\n * The effect is a stereo effect where the modulation phase is inverted in each channel.\n *\n * @example\n * // create a tremolo and start it\'s LFO\n * const tremolo = new Tone.Tremolo(9, 0.75).toDestination().start();\n * // route an oscillator through the tremolo and start it\n * const oscillator = new Tone.Oscillator().connect(tremolo).start();\n *\n * @category Effect\n */\nclass Tremolo extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Tremolo";\n const options = optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]);\n this._lfoL = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._lfoR = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._amplitudeL = new Gain({ context: this.context });\n this._amplitudeR = new Gain({ context: this.context });\n this.frequency = new Signal({\n context: this.context,\n value: options.frequency,\n units: "frequency",\n });\n this.depth = new Signal({\n context: this.context,\n value: options.depth,\n units: "normalRange",\n });\n readOnly(this, ["frequency", "depth"]);\n this.connectEffectLeft(this._amplitudeL);\n this.connectEffectRight(this._amplitudeR);\n this._lfoL.connect(this._amplitudeL.gain);\n this._lfoR.connect(this._amplitudeR.gain);\n this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency);\n this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude);\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 10,\n type: "sine",\n depth: 0.5,\n spread: 180,\n });\n }\n /**\n * Start the tremolo.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the tremolo.\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the effect to the transport.\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the filter from the transport\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * The oscillator type.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase; // 180\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._amplitudeL.dispose();\n this._amplitudeR.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Tremolo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Vibrato.js\n\n\n\n\n\n/**\n * A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO\n * modulates the delayTime of the delay, causing the pitch to rise and fall.\n * @category Effect\n */\nclass Vibrato extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Vibrato";\n const options = optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: 0,\n maxDelay: options.maxDelay,\n });\n this._lfo = new LFO({\n context: this.context,\n type: options.type,\n min: 0,\n max: options.maxDelay,\n frequency: options.frequency,\n phase: -90 // offse the phase so the resting position is in the center\n }).start().connect(this._delayNode.delayTime);\n this.frequency = this._lfo.frequency;\n this.depth = this._lfo.amplitude;\n this.depth.value = options.depth;\n readOnly(this, ["frequency", "depth"]);\n this.effectSend.chain(this._delayNode, this.effectReturn);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n maxDelay: 0.005,\n frequency: 5,\n depth: 0.1,\n type: "sine"\n });\n }\n /**\n * Type of oscillator attached to the Vibrato.\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Vibrato.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Analyser.js\n\n\n\n\n\n/**\n * Wrapper around the native Web Audio\'s [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).\n * Extracts FFT or Waveform data from the incoming signal.\n * @category Component\n */\nclass Analyser_Analyser extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]));\n this.name = "Analyser";\n /**\n * The analyser node.\n */\n this._analysers = [];\n /**\n * The buffer that the FFT data is written to\n */\n this._buffers = [];\n const options = optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]);\n this.input = this.output = this._gain = new Gain({ context: this.context });\n this._split = new Split({\n context: this.context,\n channels: options.channels,\n });\n this.input.connect(this._split);\n assertRange(options.channels, 1);\n // create the analysers\n for (let channel = 0; channel < options.channels; channel++) {\n this._analysers[channel] = this.context.createAnalyser();\n this._split.connect(this._analysers[channel], channel, 0);\n }\n // set the values initially\n this.size = options.size;\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n size: 1024,\n smoothing: 0.8,\n type: "fft",\n channels: 1,\n });\n }\n /**\n * Run the analysis given the current settings. If [[channels]] = 1,\n * it will return a Float32Array. If [[channels]] > 1, it will\n * return an array of Float32Arrays where each index in the array\n * represents the analysis done on a channel.\n */\n getValue() {\n this._analysers.forEach((analyser, index) => {\n const buffer = this._buffers[index];\n if (this._type === "fft") {\n analyser.getFloatFrequencyData(buffer);\n }\n else if (this._type === "waveform") {\n analyser.getFloatTimeDomainData(buffer);\n }\n });\n if (this.channels === 1) {\n return this._buffers[0];\n }\n else {\n return this._buffers;\n }\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n */\n get size() {\n return this._analysers[0].frequencyBinCount;\n }\n set size(size) {\n this._analysers.forEach((analyser, index) => {\n analyser.fftSize = size * 2;\n this._buffers[index] = new Float32Array(size);\n });\n }\n /**\n * The number of channels the analyser does the analysis on. Channel\n * separation is done using [[Split]]\n */\n get channels() {\n return this._analysers.length;\n }\n /**\n * The analysis function returned by analyser.getValue(), either "fft" or "waveform".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type === "waveform" || type === "fft", `Analyser: invalid type: ${type}`);\n this._type = type;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analysers[0].smoothingTimeConstant;\n }\n set smoothing(val) {\n this._analysers.forEach(a => a.smoothingTimeConstant = val);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._analysers.forEach(a => a.disconnect());\n this._split.dispose();\n this._gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Analyser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/MeterBase.js\n\n\n\n/**\n * The base class for Metering classes.\n */\nclass MeterBase_MeterBase extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MeterBase_MeterBase.getDefaults(), arguments));\n this.name = "MeterBase";\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n });\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MeterBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Meter.js\n\n\n\n\n\n/**\n * Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)\n * of an input signal. It can also get the raw value of the input signal.\n *\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * setInterval(() => console.log(meter.getValue()), 100);\n * @category Component\n */\nclass Meter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]));\n this.name = "Meter";\n /**\n * The previous frame\'s value\n */\n this._rms = 0;\n const options = optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]);\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n channels: options.channels,\n });\n this.smoothing = options.smoothing,\n this.normalRange = options.normalRange;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n smoothing: 0.8,\n normalRange: false,\n channels: 1,\n });\n }\n /**\n * Use [[getValue]] instead. For the previous getValue behavior, use DCMeter.\n * @deprecated\n */\n getLevel() {\n warn("\'getLevel\' has been changed to \'getValue\'");\n return this.getValue();\n }\n /**\n * Get the current value of the incoming signal.\n * Output is in decibels when [[normalRange]] is `false`.\n * If [[channels]] = 1, then the output is a single number\n * representing the value of the input signal. When [[channels]] > 1,\n * then each channel is returned as a value in a number array.\n */\n getValue() {\n const aValues = this._analyser.getValue();\n const channelValues = this.channels === 1 ? [aValues] : aValues;\n const vals = channelValues.map(values => {\n const totalSquared = values.reduce((total, current) => total + current * current, 0);\n const rms = Math.sqrt(totalSquared / values.length);\n // the rms can only fall at the rate of the smoothing\n // but can jump up instantly\n this._rms = Math.max(rms, this._rms * this.smoothing);\n return this.normalRange ? this._rms : gainToDb(this._rms);\n });\n if (this.channels === 1) {\n return vals[0];\n }\n else {\n return vals;\n }\n }\n /**\n * The number of channels of analysis.\n */\n get channels() {\n return this._analyser.channels;\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Meter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/FFT.js\n\n\n\n\n\n/**\n * Get the current frequency data of the connected audio source using a fast Fourier transform.\n * @category Component\n */\nclass FFT extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(FFT.getDefaults(), arguments, ["size"]));\n this.name = "FFT";\n const options = optionsFromArguments(FFT.getDefaults(), arguments, ["size"]);\n this.normalRange = options.normalRange;\n this._analyser.type = "fft";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalRange: false,\n size: 1024,\n smoothing: 0.8,\n });\n }\n /**\n * Gets the current frequency data from the connected audio source.\n * Returns the frequency data of length [[size]] as a Float32Array of decibel values.\n */\n getValue() {\n const values = this._analyser.getValue();\n return values.map(v => this.normalRange ? dbToGain(v) : v);\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]] (i.e. the number of\n * frequency bins). Large FFT sizes may be costly to compute.\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analyser.smoothing;\n }\n set smoothing(val) {\n this._analyser.smoothing = val;\n }\n /**\n * Returns the frequency value in hertz of each of the indices of the FFT\'s [[getValue]] response.\n * @example\n * const fft = new Tone.FFT(32);\n * console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index)));\n */\n getFrequencyOfIndex(index) {\n assert(0 <= index && index < this.size, `index must be greater than or equal to 0 and less than ${this.size}`);\n return index * this.context.sampleRate / (this.size * 2);\n }\n}\n//# sourceMappingURL=FFT.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/DCMeter.js\n\n\n/**\n * DCMeter gets the raw value of the input signal at the current time.\n *\n * @example\n * const meter = new Tone.DCMeter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * const level = meter.getValue();\n * @category Component\n */\nclass DCMeter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(DCMeter.getDefaults(), arguments));\n this.name = "DCMeter";\n this._analyser.type = "waveform";\n this._analyser.size = 256;\n }\n /**\n * Get the signal value of the incoming signal\n */\n getValue() {\n const value = this._analyser.getValue();\n return value[0];\n }\n}\n//# sourceMappingURL=DCMeter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Waveform.js\n\n\n/**\n * Get the current waveform data of the connected audio source.\n * @category Component\n */\nclass Waveform extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]));\n this.name = "Waveform";\n const options = optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]);\n this._analyser.type = "waveform";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n size: 1024,\n });\n }\n /**\n * Return the waveform for the current time as a Float32Array where each value in the array\n * represents a sample in the waveform.\n */\n getValue() {\n return this._analyser.getValue();\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]].\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n}\n//# sourceMappingURL=Waveform.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Solo.js\n\n\n\n/**\n * Solo lets you isolate a specific audio stream. When an instance is set to `solo=true`,\n * it will mute all other instances of Solo.\n * @example\n * const soloA = new Tone.Solo().toDestination();\n * const oscA = new Tone.Oscillator("C4", "sawtooth").connect(soloA);\n * const soloB = new Tone.Solo().toDestination();\n * const oscB = new Tone.Oscillator("E4", "square").connect(soloB);\n * soloA.solo = true;\n * // no audio will pass through soloB\n * @category Component\n */\nclass Solo extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]));\n this.name = "Solo";\n const options = Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n });\n if (!Solo._allSolos.has(this.context)) {\n Solo._allSolos.set(this.context, new Set());\n }\n Solo._allSolos.get(this.context).add(this);\n // set initially\n this.solo = options.solo;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n solo: false,\n });\n }\n /**\n * Isolates this instance and mutes all other instances of Solo.\n * Only one instance can be soloed at a time. A soloed\n * instance will report `solo=false` when another instance is soloed.\n */\n get solo() {\n return this._isSoloed();\n }\n set solo(solo) {\n if (solo) {\n this._addSolo();\n }\n else {\n this._removeSolo();\n }\n Solo._allSolos.get(this.context).forEach(instance => instance._updateSolo());\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed\n */\n get muted() {\n return this.input.gain.value === 0;\n }\n /**\n * Add this to the soloed array\n */\n _addSolo() {\n if (!Solo._soloed.has(this.context)) {\n Solo._soloed.set(this.context, new Set());\n }\n Solo._soloed.get(this.context).add(this);\n }\n /**\n * Remove this from the soloed array\n */\n _removeSolo() {\n if (Solo._soloed.has(this.context)) {\n Solo._soloed.get(this.context).delete(this);\n }\n }\n /**\n * Is this on the soloed array\n */\n _isSoloed() {\n return Solo._soloed.has(this.context) && Solo._soloed.get(this.context).has(this);\n }\n /**\n * Returns true if no one is soloed\n */\n _noSolos() {\n // either does not have any soloed added\n return !Solo._soloed.has(this.context) ||\n // or has a solo set but doesn\'t include any items\n (Solo._soloed.has(this.context) && Solo._soloed.get(this.context).size === 0);\n }\n /**\n * Solo the current instance and unsolo all other instances.\n */\n _updateSolo() {\n if (this._isSoloed()) {\n this.input.gain.value = 1;\n }\n else if (this._noSolos()) {\n // no one is soloed\n this.input.gain.value = 1;\n }\n else {\n this.input.gain.value = 0;\n }\n }\n dispose() {\n super.dispose();\n Solo._allSolos.get(this.context).delete(this);\n this._removeSolo();\n return this;\n }\n}\n/**\n * Hold all of the solo\'ed tracks belonging to a specific context\n */\nSolo._allSolos = new Map();\n/**\n * Hold the currently solo\'ed instance(s)\n */\nSolo._soloed = new Map();\n//# sourceMappingURL=Solo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/PanVol.js\n\n\n\n\n\n/**\n * PanVol is a Tone.Panner and Tone.Volume in one.\n * @example\n * // pan the incoming signal left and drop the volume\n * const panVol = new Tone.PanVol(-0.25, -12).toDestination();\n * const osc = new Tone.Oscillator().connect(panVol).start();\n * @category Component\n */\nclass PanVol extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]));\n this.name = "PanVol";\n const options = Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]);\n this._panner = this.input = new Panner_Panner({\n context: this.context,\n pan: options.pan,\n channelCount: options.channelCount,\n });\n this.pan = this._panner.pan;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n // connections\n this._panner.connect(this._volume);\n this.mute = options.mute;\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n pan: 0,\n volume: 0,\n channelCount: 1,\n });\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n this.pan.dispose();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PanVol.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Channel.js\n\n\n\n\n\n\n/**\n * Channel provides a channel strip interface with volume, pan, solo and mute controls.\n * See [[PanVol]] and [[Solo]]\n * @example\n * // pan the incoming signal left and drop the volume 12db\n * const channel = new Tone.Channel(-0.25, -12);\n * @category Component\n */\nclass Channel extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]));\n this.name = "Channel";\n const options = Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]);\n this._solo = this.input = new Solo({\n solo: options.solo,\n context: this.context,\n });\n this._panVol = this.output = new PanVol({\n context: this.context,\n pan: options.pan,\n volume: options.volume,\n mute: options.mute,\n channelCount: options.channelCount\n });\n this.pan = this._panVol.pan;\n this.volume = this._panVol.volume;\n this._solo.connect(this._panVol);\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n volume: 0,\n mute: false,\n solo: false,\n channelCount: 1,\n });\n }\n /**\n * Solo/unsolo the channel. Soloing is only relative to other [[Channels]] and [[Solo]] instances\n */\n get solo() {\n return this._solo.solo;\n }\n set solo(solo) {\n this._solo.solo = solo;\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed,\n * or the channel is muted\n */\n get muted() {\n return this._solo.muted || this.mute;\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._panVol.mute;\n }\n set mute(mute) {\n this._panVol.mute = mute;\n }\n /**\n * Get the gain node belonging to the bus name. Create it if\n * it doesn\'t exist\n * @param name The bus name\n */\n _getBus(name) {\n if (!Channel.buses.has(name)) {\n Channel.buses.set(name, new Gain_Gain({ context: this.context }));\n }\n return Channel.buses.get(name);\n }\n /**\n * Send audio to another channel using a string. `send` is a lot like\n * [[connect]], except it uses a string instead of an object. This can\n * be useful in large applications to decouple sections since [[send]]\n * and [[receive]] can be invoked separately in order to connect an object\n * @param name The channel name to send the audio\n * @param volume The amount of the signal to send.\n * \tDefaults to 0db, i.e. send the entire signal\n * @returns Returns the gain node of this connection.\n */\n send(name, volume = 0) {\n const bus = this._getBus(name);\n const sendKnob = new Gain_Gain({\n context: this.context,\n units: "decibels",\n gain: volume,\n });\n this.connect(sendKnob);\n sendKnob.connect(bus);\n return sendKnob;\n }\n /**\n * Receive audio from a channel which was connected with [[send]].\n * @param name The channel name to receive audio from.\n */\n receive(name) {\n const bus = this._getBus(name);\n bus.connect(this);\n return this;\n }\n dispose() {\n super.dispose();\n this._panVol.dispose();\n this.pan.dispose();\n this.volume.dispose();\n this._solo.dispose();\n return this;\n }\n}\n/**\n * Store the send/receive channels by name.\n */\nChannel.buses = new Map();\n//# sourceMappingURL=Channel.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Mono.js\n\n\n\n\n/**\n * Mono coerces the incoming mono or stereo signal into a mono signal\n * where both left and right channels have the same value. This can be useful\n * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).\n * @category Component\n */\nclass Mono extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Mono.getDefaults(), arguments));\n this.name = "Mono";\n this.input = new Gain({ context: this.context });\n this._merge = this.output = new Merge({\n channels: 2,\n context: this.context,\n });\n this.input.connect(this._merge, 0, 0);\n this.input.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this._merge.dispose();\n this.input.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Mono.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MultibandSplit.js\n\n\n\n\n\n\n/**\n * Split the incoming signal into three bands (low, mid, high)\n * with two crossover frequency controls.\n * ```\n * +----------------------+\n * +-> input < lowFrequency +------------------\x3e low\n * | +----------------------+\n * |\n * | +--------------------------------------+\n * input ---+-> lowFrequency < input < highFrequency +--\x3e mid\n * | +--------------------------------------+\n * |\n * | +-----------------------+\n * +-> highFrequency < input +-----------------\x3e high\n * +-----------------------+\n * ```\n * @category Component\n */\nclass MultibandSplit_MultibandSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]));\n this.name = "MultibandSplit";\n /**\n * the input\n */\n this.input = new Gain({ context: this.context });\n /**\n * no output node, use either low, mid or high outputs\n */\n this.output = undefined;\n /**\n * The low band.\n */\n this.low = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * the lower filter of the mid band\n */\n this._lowMidFilter = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n /**\n * The mid band output.\n */\n this.mid = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * The high band output.\n */\n this.high = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n this._internalChannels = [this.low, this.mid, this.high];\n const options = optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]);\n this.lowFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.lowFrequency,\n });\n this.highFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.highFrequency,\n });\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.input.fan(this.low, this.high);\n this.input.chain(this._lowMidFilter, this.mid);\n // the frequency control signal\n this.lowFrequency.fan(this.low.frequency, this._lowMidFilter.frequency);\n this.highFrequency.fan(this.mid.frequency, this.high.frequency);\n // the Q value\n this.Q.connect(this.low.Q);\n this.Q.connect(this._lowMidFilter.Q);\n this.Q.connect(this.mid.Q);\n this.Q.connect(this.high.Q);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n highFrequency: 2500,\n lowFrequency: 400,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n this.low.dispose();\n this._lowMidFilter.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Listener.js\n\n\n\n/**\n * Tone.Listener is a thin wrapper around the AudioListener. Listener combined\n * with [[Panner3D]] makes up the Web Audio API\'s 3D panning system. Panner3D allows you\n * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from\n * a first-person perspective. There is only one listener per audio context.\n */\nclass Listener extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(...arguments);\n this.name = "Listener";\n this.positionX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionX,\n });\n this.positionY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionY,\n });\n this.positionZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionZ,\n });\n this.forwardX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardX,\n });\n this.forwardY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardY,\n });\n this.forwardZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardZ,\n });\n this.upX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upX,\n });\n this.upY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upY,\n });\n this.upZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n forwardX: 0,\n forwardY: 0,\n forwardZ: -1,\n upX: 0,\n upY: 1,\n upZ: 0,\n });\n }\n dispose() {\n super.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n this.forwardX.dispose();\n this.forwardY.dispose();\n this.forwardZ.dispose();\n this.upX.dispose();\n this.upY.dispose();\n this.upZ.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.listener = new Listener({ context });\n});\nonContextClose(context => {\n context.listener.dispose();\n});\n//# sourceMappingURL=Listener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner3D.js\n\n\n\n\n/**\n * A spatialized panner node which supports equalpower or HRTF panning.\n * @category Component\n */\nclass Panner3D extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]));\n this.name = "Panner3D";\n const options = optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]);\n this._panner = this.input = this.output = this.context.createPanner();\n // set some values\n this.panningModel = options.panningModel;\n this.maxDistance = options.maxDistance;\n this.distanceModel = options.distanceModel;\n this.coneOuterGain = options.coneOuterGain;\n this.coneOuterAngle = options.coneOuterAngle;\n this.coneInnerAngle = options.coneInnerAngle;\n this.refDistance = options.refDistance;\n this.rolloffFactor = options.rolloffFactor;\n this.positionX = new Param({\n context: this.context,\n param: this._panner.positionX,\n value: options.positionX,\n });\n this.positionY = new Param({\n context: this.context,\n param: this._panner.positionY,\n value: options.positionY,\n });\n this.positionZ = new Param({\n context: this.context,\n param: this._panner.positionZ,\n value: options.positionZ,\n });\n this.orientationX = new Param({\n context: this.context,\n param: this._panner.orientationX,\n value: options.orientationX,\n });\n this.orientationY = new Param({\n context: this.context,\n param: this._panner.orientationY,\n value: options.orientationY,\n });\n this.orientationZ = new Param({\n context: this.context,\n param: this._panner.orientationZ,\n value: options.orientationZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: "inverse",\n maxDistance: 10000,\n orientationX: 0,\n orientationY: 0,\n orientationZ: 0,\n panningModel: "equalpower",\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1,\n });\n }\n /**\n * Sets the position of the source in 3d space.\n */\n setPosition(x, y, z) {\n this.positionX.value = x;\n this.positionY.value = y;\n this.positionZ.value = z;\n return this;\n }\n /**\n * Sets the orientation of the source in 3d space.\n */\n setOrientation(x, y, z) {\n this.orientationX.value = x;\n this.orientationY.value = y;\n this.orientationZ.value = z;\n return this;\n }\n /**\n * The panning model. Either "equalpower" or "HRTF".\n */\n get panningModel() {\n return this._panner.panningModel;\n }\n set panningModel(val) {\n this._panner.panningModel = val;\n }\n /**\n * A reference distance for reducing volume as source move further from the listener\n */\n get refDistance() {\n return this._panner.refDistance;\n }\n set refDistance(val) {\n this._panner.refDistance = val;\n }\n /**\n * Describes how quickly the volume is reduced as source moves away from listener.\n */\n get rolloffFactor() {\n return this._panner.rolloffFactor;\n }\n set rolloffFactor(val) {\n this._panner.rolloffFactor = val;\n }\n /**\n * The distance model used by, "linear", "inverse", or "exponential".\n */\n get distanceModel() {\n return this._panner.distanceModel;\n }\n set distanceModel(val) {\n this._panner.distanceModel = val;\n }\n /**\n * The angle, in degrees, inside of which there will be no volume reduction\n */\n get coneInnerAngle() {\n return this._panner.coneInnerAngle;\n }\n set coneInnerAngle(val) {\n this._panner.coneInnerAngle = val;\n }\n /**\n * The angle, in degrees, outside of which the volume will be reduced\n * to a constant value of coneOuterGain\n */\n get coneOuterAngle() {\n return this._panner.coneOuterAngle;\n }\n set coneOuterAngle(val) {\n this._panner.coneOuterAngle = val;\n }\n /**\n * The gain outside of the coneOuterAngle\n */\n get coneOuterGain() {\n return this._panner.coneOuterGain;\n }\n set coneOuterGain(val) {\n this._panner.coneOuterGain = val;\n }\n /**\n * The maximum distance between source and listener,\n * after which the volume will not be reduced any further.\n */\n get maxDistance() {\n return this._panner.maxDistance;\n }\n set maxDistance(val) {\n this._panner.maxDistance = val;\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.orientationX.dispose();\n this.orientationY.dispose();\n this.orientationZ.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner3D.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Recorder.js\n\n\n\n\n\n\n/**\n * A wrapper around the MediaRecorder API. Unlike the rest of Tone.js, this module does not offer\n * any sample-accurate scheduling because it is not a feature of the MediaRecorder API.\n * This is only natively supported in Chrome and Firefox.\n * For a cross-browser shim, install (audio-recorder-polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n * @example\n * const recorder = new Tone.Recorder();\n * const synth = new Tone.Synth().connect(recorder);\n * // start recording\n * recorder.start();\n * // generate a few notes\n * synth.triggerAttackRelease("C3", 0.5);\n * synth.triggerAttackRelease("C4", 0.5, "+1");\n * synth.triggerAttackRelease("C5", 0.5, "+2");\n * // wait for the notes to end and stop the recording\n * setTimeout(async () => {\n * \t// the recorded audio is returned as a blob\n * \tconst recording = await recorder.stop();\n * \t// download the recording by creating an anchor element and blob url\n * \tconst url = URL.createObjectURL(recording);\n * \tconst anchor = document.createElement("a");\n * \tanchor.download = "recording.webm";\n * \tanchor.href = url;\n * \tanchor.click();\n * }, 4000);\n * @category Component\n */\nclass Recorder extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Recorder.getDefaults(), arguments));\n this.name = "Recorder";\n const options = optionsFromArguments(Recorder.getDefaults(), arguments);\n this.input = new Gain({\n context: this.context\n });\n assert(Recorder.supported, "Media Recorder API is not available");\n this._stream = this.context.createMediaStreamDestination();\n this.input.connect(this._stream);\n this._recorder = new MediaRecorder(this._stream.stream, {\n mimeType: options.mimeType\n });\n }\n static getDefaults() {\n return ToneAudioNode.getDefaults();\n }\n /**\n * The mime type is the format that the audio is encoded in. For Chrome\n * that is typically webm encoded as "vorbis".\n */\n get mimeType() {\n return this._recorder.mimeType;\n }\n /**\n * Test if your platform supports the Media Recorder API. If it\'s not available,\n * try installing this (polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n */\n static get supported() {\n return theWindow !== null && Reflect.has(theWindow, "MediaRecorder");\n }\n /**\n * Get the playback state of the Recorder, either "started", "stopped" or "paused"\n */\n get state() {\n if (this._recorder.state === "inactive") {\n return "stopped";\n }\n else if (this._recorder.state === "paused") {\n return "paused";\n }\n else {\n return "started";\n }\n }\n /**\n * Start the Recorder. Returns a promise which resolves\n * when the recorder has started.\n */\n start() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "started", "Recorder is already started");\n const startPromise = new Promise(done => {\n const handleStart = () => {\n this._recorder.removeEventListener("start", handleStart, false);\n done();\n };\n this._recorder.addEventListener("start", handleStart, false);\n });\n this._recorder.start();\n return yield startPromise;\n });\n }\n /**\n * Stop the recorder. Returns a promise with the recorded content until this point\n * encoded as [[mimeType]]\n */\n stop() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "stopped", "Recorder is not started");\n const dataPromise = new Promise(done => {\n const handleData = (e) => {\n this._recorder.removeEventListener("dataavailable", handleData, false);\n done(e.data);\n };\n this._recorder.addEventListener("dataavailable", handleData, false);\n });\n this._recorder.stop();\n return yield dataPromise;\n });\n }\n /**\n * Pause the recorder\n */\n pause() {\n assert(this.state === "started", "Recorder must be started");\n this._recorder.pause();\n return this;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._stream.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Recorder.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Compressor.js\n\n\n\n\n/**\n * Compressor is a thin wrapper around the Web Audio\n * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).\n * Compression reduces the volume of loud sounds or amplifies quiet sounds\n * by narrowing or "compressing" an audio signal\'s dynamic range.\n * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).\n * @example\n * const comp = new Tone.Compressor(-30, 3);\n * @category Component\n */\nclass Compressor_Compressor extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]));\n this.name = "Compressor";\n /**\n * the compressor node\n */\n this._compressor = this.context.createDynamicsCompressor();\n this.input = this._compressor;\n this.output = this._compressor;\n const options = Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]);\n this.threshold = new Param_Param({\n minValue: this._compressor.threshold.minValue,\n maxValue: this._compressor.threshold.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.threshold,\n units: "decibels",\n value: options.threshold,\n });\n this.attack = new Param_Param({\n minValue: this._compressor.attack.minValue,\n maxValue: this._compressor.attack.maxValue,\n context: this.context,\n param: this._compressor.attack,\n units: "time",\n value: options.attack,\n });\n this.release = new Param_Param({\n minValue: this._compressor.release.minValue,\n maxValue: this._compressor.release.maxValue,\n context: this.context,\n param: this._compressor.release,\n units: "time",\n value: options.release,\n });\n this.knee = new Param_Param({\n minValue: this._compressor.knee.minValue,\n maxValue: this._compressor.knee.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.knee,\n units: "decibels",\n value: options.knee,\n });\n this.ratio = new Param_Param({\n minValue: this._compressor.ratio.minValue,\n maxValue: this._compressor.ratio.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.ratio,\n units: "positive",\n value: options.ratio,\n });\n // set the defaults\n Interface_readOnly(this, ["knee", "release", "attack", "ratio", "threshold"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.003,\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24,\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal. If fed no signal the value will be 0 (no gain reduction).\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.disconnect();\n this.attack.dispose();\n this.release.dispose();\n this.threshold.dispose();\n this.ratio.dispose();\n this.knee.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Compressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Gate.js\n\n\n\n\n\n\n/**\n * Gate only passes a signal through when the incoming\n * signal exceeds a specified threshold. It uses [[Follower]] to follow the ampltiude\n * of the incoming signal and compares it to the [[threshold]] value using [[GreaterThan]].\n *\n * @example\n * const gate = new Tone.Gate(-30, 0.2).toDestination();\n * const mic = new Tone.UserMedia().connect(gate);\n * // the gate will only pass through the incoming\n * // signal when it\'s louder than -30db\n * @category Component\n */\nclass Gate extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"])));\n this.name = "Gate";\n const options = optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.smoothing,\n });\n this._gt = new GreaterThan({\n context: this.context,\n value: dbToGain(options.threshold),\n });\n this.input = new Gain({ context: this.context });\n this._gate = this.output = new Gain({ context: this.context });\n // connections\n this.input.connect(this._gate);\n // the control signal\n this.input.chain(this._follower, this._gt, this._gate.gain);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.1,\n threshold: -40\n });\n }\n /**\n * The threshold of the gate in decibels\n */\n get threshold() {\n return gainToDb(this._gt.value);\n }\n set threshold(thresh) {\n this._gt.value = dbToGain(thresh);\n }\n /**\n * The attack/decay speed of the gate. See [[Follower.smoothing]]\n */\n get smoothing() {\n return this._follower.smoothing;\n }\n set smoothing(smoothingTime) {\n this._follower.smoothing = smoothingTime;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._follower.dispose();\n this._gt.dispose();\n this._gate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Limiter.js\n\n\n\n\n;\n/**\n * Limiter will limit the loudness of an incoming signal.\n * Under the hood it\'s composed of a [[Compressor]] with a fast attack\n * and release and max compression ratio.\n *\n * @example\n * const limiter = new Tone.Limiter(-20).toDestination();\n * const oscillator = new Tone.Oscillator().connect(limiter);\n * oscillator.start();\n * @category Component\n */\nclass Limiter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"])));\n this.name = "Limiter";\n const options = optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"]);\n this._compressor = this.input = this.output = new Compressor({\n context: this.context,\n ratio: 20,\n attack: 0.003,\n release: 0.01,\n threshold: options.threshold\n });\n this.threshold = this._compressor.threshold;\n readOnly(this, "threshold");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n threshold: -12\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal.\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.dispose();\n this.threshold.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Limiter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MidSideCompressor.js\n\n\n\n\n\n\n/**\n * MidSideCompressor applies two different compressors to the [[mid]]\n * and [[side]] signal components of the input. See [[MidSideSplit]] and [[MidSideMerge]].\n * @category Component\n */\nclass MidSideCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MidSideCompressor.getDefaults(), arguments)));\n this.name = "MidSideCompressor";\n const options = optionsFromArguments(MidSideCompressor.getDefaults(), arguments);\n this._midSideSplit = this.input = new MidSideSplit({ context: this.context });\n this._midSideMerge = this.output = new MidSideMerge({ context: this.context });\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.side = new Compressor(Object.assign(options.side, { context: this.context }));\n this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);\n this._midSideSplit.side.chain(this.side, this._midSideMerge.side);\n readOnly(this, ["mid", "side"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n side: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n }\n });\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MultibandCompressor.js\n\n\n\n\n\n\n/**\n * A compressor with separate controls over low/mid/high dynamics. See [[Compressor]] and [[MultibandSplit]]\n *\n * @example\n * const multiband = new Tone.MultibandCompressor({\n * \tlowFrequency: 200,\n * \thighFrequency: 1300,\n * \tlow: {\n * \t\tthreshold: -12\n * \t}\n * });\n * @category Component\n */\nclass MultibandCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MultibandCompressor.getDefaults(), arguments)));\n this.name = "MultibandCompressor";\n const options = optionsFromArguments(MultibandCompressor.getDefaults(), arguments);\n this._splitter = this.input = new MultibandSplit({\n context: this.context,\n lowFrequency: options.lowFrequency,\n highFrequency: options.highFrequency\n });\n this.lowFrequency = this._splitter.lowFrequency;\n this.highFrequency = this._splitter.highFrequency;\n this.output = new Gain({ context: this.context });\n this.low = new Compressor(Object.assign(options.low, { context: this.context }));\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.high = new Compressor(Object.assign(options.high, { context: this.context }));\n // connect the compressor\n this._splitter.low.chain(this.low, this.output);\n this._splitter.mid.chain(this.mid, this.output);\n this._splitter.high.chain(this.high, this.output);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n lowFrequency: 250,\n highFrequency: 2000,\n low: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n },\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n high: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n });\n }\n dispose() {\n super.dispose();\n this._splitter.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.output.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/EQ3.js\n\n\n\n\n\n/**\n * EQ3 provides 3 equalizer bins: Low/Mid/High.\n * @category Component\n */\nclass EQ3 extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]));\n this.name = "EQ3";\n /**\n * the output\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [];\n const options = optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]);\n this.input = this._multibandSplit = new MultibandSplit({\n context: this.context,\n highFrequency: options.highFrequency,\n lowFrequency: options.lowFrequency,\n });\n this._lowGain = new Gain({\n context: this.context,\n gain: options.low,\n units: "decibels",\n });\n this._midGain = new Gain({\n context: this.context,\n gain: options.mid,\n units: "decibels",\n });\n this._highGain = new Gain({\n context: this.context,\n gain: options.high,\n units: "decibels",\n });\n this.low = this._lowGain.gain;\n this.mid = this._midGain.gain;\n this.high = this._highGain.gain;\n this.Q = this._multibandSplit.Q;\n this.lowFrequency = this._multibandSplit.lowFrequency;\n this.highFrequency = this._multibandSplit.highFrequency;\n // the frequency bands\n this._multibandSplit.low.chain(this._lowGain, this.output);\n this._multibandSplit.mid.chain(this._midGain, this.output);\n this._multibandSplit.high.chain(this._highGain, this.output);\n readOnly(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._internalChannels = [this._multibandSplit];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n high: 0,\n highFrequency: 2500,\n low: 0,\n lowFrequency: 400,\n mid: 0,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._multibandSplit.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this._lowGain.dispose();\n this._midGain.dispose();\n this._highGain.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=EQ3.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Convolver.js\n\n\n\n\n\n\n/**\n * Convolver is a wrapper around the Native Web Audio\n * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface).\n * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on\n * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb).\n *\n * @example\n * // initializing the convolver with an impulse response\n * const convolver = new Tone.Convolver("./path/to/ir.wav").toDestination();\n * @category Component\n */\nclass Convolver extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Convolver";\n /**\n * The native ConvolverNode\n */\n this._convolver = this.context.createConvolver();\n const options = optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer(options.url, buffer => {\n this.buffer = buffer;\n options.onload();\n });\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n // set if it\'s already loaded, set it immediately\n if (this._buffer.loaded) {\n this.buffer = this._buffer;\n }\n // initially set normalization\n this.normalize = options.normalize;\n // connect it up\n this.input.chain(this._convolver, this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalize: true,\n onload: noOp,\n });\n }\n /**\n * Load an impulse response url as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n */\n load(url) {\n return __awaiter(this, void 0, void 0, function* () {\n this.buffer = yield this._buffer.load(url);\n });\n }\n /**\n * The convolver\'s buffer\n */\n get buffer() {\n if (this._buffer.length) {\n return this._buffer;\n }\n else {\n return null;\n }\n }\n set buffer(buffer) {\n if (buffer) {\n this._buffer.set(buffer);\n }\n // if it\'s already got a buffer, create a new one\n if (this._convolver.buffer) {\n // disconnect the old one\n this.input.disconnect();\n this._convolver.disconnect();\n // create and connect a new one\n this._convolver = this.context.createConvolver();\n this.input.chain(this._convolver, this.output);\n }\n const buff = this._buffer.get();\n this._convolver.buffer = buff ? buff : null;\n }\n /**\n * The normalize property of the ConvolverNode interface is a boolean that\n * controls whether the impulse response from the buffer will be scaled by\n * an equal-power normalization when the buffer attribute is set, or not.\n */\n get normalize() {\n return this._convolver.normalize;\n }\n set normalize(norm) {\n this._convolver.normalize = norm;\n }\n dispose() {\n super.dispose();\n this._buffer.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Convolver.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/classes.js\n\n\n\n\n\n\n\n//# sourceMappingURL=classes.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/index.js\n\n\n\n\n\n\n\n/**\n * The current audio context time of the global [[Context]].\n * See [[Context.now]]\n * @category Core\n */\nfunction now() {\n return getContext().now();\n}\n/**\n * The current audio context time of the global [[Context]] without the [[Context.lookAhead]]\n * See [[Context.immediate]]\n * @category Core\n */\nfunction immediate() {\n return getContext().immediate();\n}\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nconst esm_Transport = Global_getContext().transport;\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nfunction getTransport() {\n return getContext().transport;\n}\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nconst esm_Destination = Global_getContext().destination;\n/**\n * @deprecated Use [[Destination]]\n */\nconst Master = Global_getContext().destination;\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nfunction getDestination() {\n return getContext().destination;\n}\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nconst esm_Listener = Global_getContext().listener;\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nfunction getListener() {\n return getContext().listener;\n}\n/**\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nconst esm_Draw = Global_getContext().draw;\n/**\n * Get the singleton attached to the global context.\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nfunction getDraw() {\n return getContext().draw;\n}\n/**\n * A reference to the global context\n * See [[Context]]\n */\nconst context = Global_getContext();\n/**\n * Promise which resolves when all of the loading promises are resolved.\n * Alias for static [[ToneAudioBuffer.loaded]] method.\n * @category Core\n */\nfunction loaded() {\n return ToneAudioBuffer.loaded();\n}\n// this fills in name changes from 13.x to 14.x\n\n\nconst Buffer = (/* unused pure expression or super */ null && (ToneAudioBuffer));\nconst Buffers = (/* unused pure expression or super */ null && (ToneAudioBuffers));\nconst BufferSource = (/* unused pure expression or super */ null && (ToneBufferSource));\n//# sourceMappingURL=index.js.map\n// EXTERNAL MODULE: ./src/lib/startAudioContext.js\nvar startAudioContext = __webpack_require__(631);\nvar startAudioContext_default = /*#__PURE__*/__webpack_require__.n(startAudioContext);\n;// CONCATENATED MODULE: ./src/lib/util.js\n\n\nvar isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);\nvar isIpad = navigator.userAgent.match(/iPad/i);\nvar isAndroid = navigator.userAgent.match(/Android/i);\nvar isMobile = isIphone || isIpad || isAndroid;\nvar isDesktop = !isMobile;\ndocument.body.classList.add(isMobile ? "mobile" : "desktop");\nvar browser = {\n isIphone: isIphone,\n isIpad: isIpad,\n isMobile: isMobile,\n isDesktop: isDesktop\n};\nvar choice = function choice(a) {\n return a[Math.floor(Math.random() * a.length)];\n};\nvar mod = function mod(n, m) {\n return n - m * Math.floor(n / m);\n};\nvar random = function random() {\n return Math.random();\n};\nvar rand = function rand(n) {\n return Math.random() * n;\n};\nvar randint = function randint(n) {\n return rand(n) | 0;\n};\nvar randrange = function randrange(a, b) {\n return a + rand(b - a);\n};\nvar randsign = function randsign() {\n return random() >= 0.5 ? -1 : 1;\n};\nvar randnullsign = function randnullsign() {\n var r = random();\n return r < 0.333 ? -1 : r < 0.666 ? 0 : 1;\n};\nfunction requestAudioContext(fn) {\n var container = document.createElement("div");\n var button = document.createElement("div");\n button.innerHTML = "Tap to start - please unmute your device";\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: "\'Menlo\', monospace",\n borderRadius: "3px",\n transform: "translate3D(-50%,-50%,0)",\n textAlign: "center",\n lineHeight: "1.5",\n width: "150px",\n cursor: "pointer"\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 */\n\nvar NOTE_RADIUS = 7;\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.filter(function (value) {\n return value && value[0] < time;\n }).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 = 1.1;\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 - NOTE_RADIUS / 4, y, NOTE_RADIUS, 0, 2 * Math.PI);\n ctx.fillStyle = direction ? "rgba(255,96,128,".concat(opacity, ")") : "rgba(128,255,96,".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/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]) + 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 samples: [{\n fn: "samples/707_bd.mp3"\n }, {\n fn: "samples/707_clap.mp3"\n }, {\n fn: "samples/707_ch.mp3"\n }, {\n fn: "samples/707_rim.mp3"\n }]\n});\nvar Kick = new sampler_Sampler({\n samples: [{\n fn: "samples/707_bd.mp3"\n }, {\n fn: "samples/707_bd2.mp3"\n }]\n});\nvar Snare = new sampler_Sampler({\n samples: [{\n fn: "samples/707_snare1.mp3"\n }, {\n fn: "samples/707_snare2.mp3"\n }]\n});\nvar Hat = new sampler_Sampler({\n samples: [{\n fn: "samples/707_ch.mp3"\n }, {\n fn: "samples/707_ch.mp3"\n }, {\n fn: "samples/707_ch.mp3"\n }, {\n fn: "samples/707_oh.mp3"\n }]\n});\nvar Perc = new sampler_Sampler({\n samples: [{\n fn: "samples/707_rim.mp3"\n }, {\n fn: "samples/707_tamb.mp3"\n }]\n});\nvar Cymbal = new sampler_Sampler({\n samples: [{\n fn: "samples/707_crash.mp3"\n }, {\n fn: "samples/707_ride.mp3"\n }]\n});\nvar Tom = new sampler_Sampler({\n samples: [{\n fn: "samples/707_tom1.mp3"\n }, {\n fn: "samples/707_tom2.mp3"\n }]\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_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_createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = relabi_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 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_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\n\nvar TWO_PI = 2 * Math.PI;\n\n/**\n * Wave functions\n */\nvar WAVE_SHAPES = {\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 - 1;\n },\n reverse_saw: function reverse_saw(time) {\n return 1 - time % TWO_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 settings = _ref.settings,\n parent = _ref.parent;\n relabi_classCallCheck(this, Relabi);\n this.updateTime = 1;\n this.steps = 50;\n this.waves = waves;\n this.bounds = bounds;\n this.settings = settings;\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 index;\n var step;\n var value;\n var values = [];\n var previousWaveValue = this.previousWaveValue || 0;\n\n // Weight individual waves rather than simply averaging them\n var totalWeight = this.waves.reduce(function (sum, wave) {\n return sum + wave.weight;\n }, 0.0);\n\n // Overshoot the line slightly each time\n var stepCount = this.steps;\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 var _iterator = relabi_createForOfIteratorHelper(this.waves),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var wave = _step.value;\n var waveOffset = (wave.offset || 0) + wave.frequency * this.settings.speed / this.steps + previousWaveValue * this.settings.feedback;\n var waveValue = WAVE_SHAPES[wave.shape](waveOffset);\n value += waveValue * wave.weight;\n previousWaveValue = waveValue;\n wave.offset = waveOffset;\n }\n\n // Scale to [-1, 1]\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n value /= totalWeight;\n previousWaveValue = value;\n values.push([timeOffset, value]);\n }\n this.previousWaveValue = previousWaveValue;\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 if (sound.instrument in instruments_namespaceObject) {\n instruments_namespaceObject[sound.instrument].play(time, sound);\n } else {\n sound.instrument.play(time, sound);\n }\n }\n }]);\n return Relabi;\n}();\n\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/typeof.js\nfunction typeof_typeof(obj) {\n "@babel/helpers - typeof";\n\n return typeof_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 }, typeof_typeof(obj);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPrimitive.js\n\nfunction toPrimitive_toPrimitive(input, hint) {\n if (typeof_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_typeof(res) !== "object") return res;\n throw new TypeError("@@toPrimitive must return a primitive value.");\n }\n return (hint === "string" ? String : Number)(input);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toPropertyKey.js\n\n\nfunction toPropertyKey_toPropertyKey(arg) {\n var key = toPrimitive_toPrimitive(arg, "string");\n return typeof_typeof(key) === "symbol" ? key : String(key);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js\n\nfunction _defineProperty(obj, key, value) {\n key = toPropertyKey_toPropertyKey(key);\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js\nfunction arrayLikeToArray_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js\n\nfunction _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray_arrayLikeToArray(arr);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js\nfunction _iterableToArray(iter) {\n if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js\n\nfunction unsupportedIterableToArray_unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return arrayLikeToArray_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_arrayLikeToArray(o, minLen);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js\nfunction _nonIterableSpread() {\n throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js\n\n\n\n\nfunction _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || unsupportedIterableToArray_unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js\nfunction arrayWithHoles_arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js\nfunction iterableToArrayLimit_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js\nfunction nonIterableRest_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}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\n\n\n\n\nfunction slicedToArray_slicedToArray(arr, i) {\n return arrayWithHoles_arrayWithHoles(arr) || iterableToArrayLimit_iterableToArrayLimit(arr, i) || unsupportedIterableToArray_unsupportedIterableToArray(arr, i) || nonIterableRest_nonIterableRest();\n}\n// EXTERNAL MODULE: ./node_modules/classnames/index.js\nvar classnames = __webpack_require__(184);\nvar classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/warning.js\n/* eslint-disable no-console */\nvar warned = {};\nvar preWarningFns = [];\n\n/**\n * Pre warning enable you to parse content before console.error.\n * Modify to null will prevent warning.\n */\nvar preMessage = function preMessage(fn) {\n preWarningFns.push(fn);\n};\nfunction warning(valid, message) {\n // Support uglify\n if (false) { var finalMessage; }\n}\nfunction note(valid, message) {\n // Support uglify\n if (false) { var finalMessage; }\n}\nfunction resetWarned() {\n warned = {};\n}\nfunction call(method, valid, message) {\n if (!valid && !warned[message]) {\n method(false, message);\n warned[message] = true;\n }\n}\nfunction warningOnce(valid, message) {\n call(warning, valid, message);\n}\nfunction noteOnce(valid, message) {\n call(note, valid, message);\n}\nwarningOnce.preMessage = preMessage;\nwarningOnce.resetWarned = resetWarned;\nwarningOnce.noteOnce = noteOnce;\n/* harmony default export */ const es_warning = (warningOnce);\n/* eslint-enable */\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/isEqual.js\n\n\n\n/**\n * Deeply compares two object literals.\n * @param obj1 object 1\n * @param obj2 object 2\n * @param shallow shallow compare\n * @returns\n */\nfunction isEqual(obj1, obj2) {\n var shallow = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n // https://github.com/mapbox/mapbox-gl-js/pull/5979/files#diff-fde7145050c47cc3a306856efd5f9c3016e86e859de9afbd02c879be5067e58f\n var refSet = new Set();\n function deepEqual(a, b) {\n var level = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var circular = refSet.has(a);\n es_warning(!circular, \'Warning: There may be circular references\');\n if (circular) {\n return false;\n }\n if (a === b) {\n return true;\n }\n if (shallow && level > 1) {\n return false;\n }\n refSet.add(a);\n var newLevel = level + 1;\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) {\n return false;\n }\n for (var i = 0; i < a.length; i++) {\n if (!deepEqual(a[i], b[i], newLevel)) {\n return false;\n }\n }\n return true;\n }\n if (a && b && typeof_typeof(a) === \'object\' && typeof_typeof(b) === \'object\') {\n var keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) {\n return false;\n }\n return keys.every(function (key) {\n return deepEqual(a[key], b[key], newLevel);\n });\n }\n // other\n return false;\n }\n return deepEqual(obj1, obj2);\n}\n/* harmony default export */ const es_isEqual = (isEqual);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useEvent.js\n\nfunction useEvent(callback) {\n var fnRef = react.useRef();\n fnRef.current = callback;\n var memoFn = react.useCallback(function () {\n var _fnRef$current;\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return (_fnRef$current = fnRef.current) === null || _fnRef$current === void 0 ? void 0 : _fnRef$current.call.apply(_fnRef$current, [fnRef].concat(args));\n }, []);\n return memoFn;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/canUseDom.js\nfunction canUseDom() {\n return !!(typeof window !== \'undefined\' && window.document && window.document.createElement);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useLayoutEffect.js\n\n\n\n/**\n * Wrap `React.useLayoutEffect` which will not throw warning message in test env\n */\nvar useLayoutEffect = true && canUseDom() ? react.useLayoutEffect : react.useEffect;\n/* harmony default export */ const hooks_useLayoutEffect = (useLayoutEffect);\nvar useLayoutUpdateEffect = function useLayoutUpdateEffect(callback, deps) {\n var firstMountRef = react.useRef(true);\n useLayoutEffect(function () {\n if (!firstMountRef.current) {\n return callback();\n }\n }, deps);\n\n // We tell react that first mount has passed\n useLayoutEffect(function () {\n firstMountRef.current = false;\n return function () {\n firstMountRef.current = true;\n };\n }, []);\n};\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useState.js\n\n\n/**\n * Same as React.useState but `setState` accept `ignoreDestroy` param to not to setState after destroyed.\n * We do not make this auto is to avoid real memory leak.\n * Developer should confirm it\'s safe to ignore themselves.\n */\nfunction useSafeState(defaultValue) {\n var destroyRef = react.useRef(false);\n var _React$useState = react.useState(defaultValue),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n value = _React$useState2[0],\n setValue = _React$useState2[1];\n react.useEffect(function () {\n destroyRef.current = false;\n return function () {\n destroyRef.current = true;\n };\n }, []);\n function safeSetState(updater, ignoreDestroy) {\n if (ignoreDestroy && destroyRef.current) {\n return;\n }\n setValue(updater);\n }\n return [value, safeSetState];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useMergedState.js\n\n\n\n\n/** We only think `undefined` is empty */\nfunction hasValue(value) {\n return value !== undefined;\n}\n\n/**\n * Similar to `useState` but will use props value if provided.\n * Note that internal use rc-util `useState` hook.\n */\nfunction useMergedState(defaultStateValue, option) {\n var _ref = option || {},\n defaultValue = _ref.defaultValue,\n value = _ref.value,\n onChange = _ref.onChange,\n postState = _ref.postState;\n\n // ======================= Init =======================\n var _useState = useSafeState(function () {\n if (hasValue(value)) {\n return value;\n } else if (hasValue(defaultValue)) {\n return typeof defaultValue === \'function\' ? defaultValue() : defaultValue;\n } else {\n return typeof defaultStateValue === \'function\' ? defaultStateValue() : defaultStateValue;\n }\n }),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n innerValue = _useState2[0],\n setInnerValue = _useState2[1];\n var mergedValue = value !== undefined ? value : innerValue;\n var postMergedValue = postState ? postState(mergedValue) : mergedValue;\n\n // ====================== Change ======================\n var onChangeFn = useEvent(onChange);\n var _useState3 = useSafeState([mergedValue]),\n _useState4 = slicedToArray_slicedToArray(_useState3, 2),\n prevValue = _useState4[0],\n setPrevValue = _useState4[1];\n useLayoutUpdateEffect(function () {\n var prev = prevValue[0];\n if (innerValue !== prev) {\n onChangeFn(innerValue, prev);\n }\n }, [prevValue]);\n\n // Sync value back to `undefined` when it from control to un-control\n useLayoutUpdateEffect(function () {\n if (!hasValue(value)) {\n setInnerValue(value);\n }\n }, [value]);\n\n // ====================== Update ======================\n var triggerChange = useEvent(function (updater, ignoreDestroy) {\n setInnerValue(updater, ignoreDestroy);\n setPrevValue([mergedValue], ignoreDestroy);\n });\n return [postMergedValue, triggerChange];\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js\nfunction extends_extends() {\n extends_extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return extends_extends.apply(this, arguments);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js\nfunction _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js\n\nfunction objectWithoutProperties_objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = _objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/objectSpread2.js\n\nfunction ownKeys(object, enumerableOnly) {\n var keys = Object.keys(object);\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(object);\n enumerableOnly && (symbols = symbols.filter(function (sym) {\n return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n })), keys.push.apply(keys, symbols);\n }\n return keys;\n}\nfunction _objectSpread2(target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = null != arguments[i] ? arguments[i] : {};\n i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {\n _defineProperty(target, key, source[key]);\n }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {\n Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n });\n }\n return target;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/KeyCode.js\n/**\n * @ignore\n * some key-codes definition and utils from closure-library\n * @author yiminghe@gmail.com\n */\n\nvar KeyCode = {\n /**\n * MAC_ENTER\n */\n MAC_ENTER: 3,\n /**\n * BACKSPACE\n */\n BACKSPACE: 8,\n /**\n * TAB\n */\n TAB: 9,\n /**\n * NUMLOCK on FF/Safari Mac\n */\n NUM_CENTER: 12,\n // NUMLOCK on FF/Safari Mac\n /**\n * ENTER\n */\n ENTER: 13,\n /**\n * SHIFT\n */\n SHIFT: 16,\n /**\n * CTRL\n */\n CTRL: 17,\n /**\n * ALT\n */\n ALT: 18,\n /**\n * PAUSE\n */\n PAUSE: 19,\n /**\n * CAPS_LOCK\n */\n CAPS_LOCK: 20,\n /**\n * ESC\n */\n ESC: 27,\n /**\n * SPACE\n */\n SPACE: 32,\n /**\n * PAGE_UP\n */\n PAGE_UP: 33,\n // also NUM_NORTH_EAST\n /**\n * PAGE_DOWN\n */\n PAGE_DOWN: 34,\n // also NUM_SOUTH_EAST\n /**\n * END\n */\n END: 35,\n // also NUM_SOUTH_WEST\n /**\n * HOME\n */\n HOME: 36,\n // also NUM_NORTH_WEST\n /**\n * LEFT\n */\n LEFT: 37,\n // also NUM_WEST\n /**\n * UP\n */\n UP: 38,\n // also NUM_NORTH\n /**\n * RIGHT\n */\n RIGHT: 39,\n // also NUM_EAST\n /**\n * DOWN\n */\n DOWN: 40,\n // also NUM_SOUTH\n /**\n * PRINT_SCREEN\n */\n PRINT_SCREEN: 44,\n /**\n * INSERT\n */\n INSERT: 45,\n // also NUM_INSERT\n /**\n * DELETE\n */\n DELETE: 46,\n // also NUM_DELETE\n /**\n * ZERO\n */\n ZERO: 48,\n /**\n * ONE\n */\n ONE: 49,\n /**\n * TWO\n */\n TWO: 50,\n /**\n * THREE\n */\n THREE: 51,\n /**\n * FOUR\n */\n FOUR: 52,\n /**\n * FIVE\n */\n FIVE: 53,\n /**\n * SIX\n */\n SIX: 54,\n /**\n * SEVEN\n */\n SEVEN: 55,\n /**\n * EIGHT\n */\n EIGHT: 56,\n /**\n * NINE\n */\n NINE: 57,\n /**\n * QUESTION_MARK\n */\n QUESTION_MARK: 63,\n // needs localization\n /**\n * A\n */\n A: 65,\n /**\n * B\n */\n B: 66,\n /**\n * C\n */\n C: 67,\n /**\n * D\n */\n D: 68,\n /**\n * E\n */\n E: 69,\n /**\n * F\n */\n F: 70,\n /**\n * G\n */\n G: 71,\n /**\n * H\n */\n H: 72,\n /**\n * I\n */\n I: 73,\n /**\n * J\n */\n J: 74,\n /**\n * K\n */\n K: 75,\n /**\n * L\n */\n L: 76,\n /**\n * M\n */\n M: 77,\n /**\n * N\n */\n N: 78,\n /**\n * O\n */\n O: 79,\n /**\n * P\n */\n P: 80,\n /**\n * Q\n */\n Q: 81,\n /**\n * R\n */\n R: 82,\n /**\n * S\n */\n S: 83,\n /**\n * T\n */\n T: 84,\n /**\n * U\n */\n U: 85,\n /**\n * V\n */\n V: 86,\n /**\n * W\n */\n W: 87,\n /**\n * X\n */\n X: 88,\n /**\n * Y\n */\n Y: 89,\n /**\n * Z\n */\n Z: 90,\n /**\n * META\n */\n META: 91,\n // WIN_KEY_LEFT\n /**\n * WIN_KEY_RIGHT\n */\n WIN_KEY_RIGHT: 92,\n /**\n * CONTEXT_MENU\n */\n CONTEXT_MENU: 93,\n /**\n * NUM_ZERO\n */\n NUM_ZERO: 96,\n /**\n * NUM_ONE\n */\n NUM_ONE: 97,\n /**\n * NUM_TWO\n */\n NUM_TWO: 98,\n /**\n * NUM_THREE\n */\n NUM_THREE: 99,\n /**\n * NUM_FOUR\n */\n NUM_FOUR: 100,\n /**\n * NUM_FIVE\n */\n NUM_FIVE: 101,\n /**\n * NUM_SIX\n */\n NUM_SIX: 102,\n /**\n * NUM_SEVEN\n */\n NUM_SEVEN: 103,\n /**\n * NUM_EIGHT\n */\n NUM_EIGHT: 104,\n /**\n * NUM_NINE\n */\n NUM_NINE: 105,\n /**\n * NUM_MULTIPLY\n */\n NUM_MULTIPLY: 106,\n /**\n * NUM_PLUS\n */\n NUM_PLUS: 107,\n /**\n * NUM_MINUS\n */\n NUM_MINUS: 109,\n /**\n * NUM_PERIOD\n */\n NUM_PERIOD: 110,\n /**\n * NUM_DIVISION\n */\n NUM_DIVISION: 111,\n /**\n * F1\n */\n F1: 112,\n /**\n * F2\n */\n F2: 113,\n /**\n * F3\n */\n F3: 114,\n /**\n * F4\n */\n F4: 115,\n /**\n * F5\n */\n F5: 116,\n /**\n * F6\n */\n F6: 117,\n /**\n * F7\n */\n F7: 118,\n /**\n * F8\n */\n F8: 119,\n /**\n * F9\n */\n F9: 120,\n /**\n * F10\n */\n F10: 121,\n /**\n * F11\n */\n F11: 122,\n /**\n * F12\n */\n F12: 123,\n /**\n * NUMLOCK\n */\n NUMLOCK: 144,\n /**\n * SEMICOLON\n */\n SEMICOLON: 186,\n // needs localization\n /**\n * DASH\n */\n DASH: 189,\n // needs localization\n /**\n * EQUALS\n */\n EQUALS: 187,\n // needs localization\n /**\n * COMMA\n */\n COMMA: 188,\n // needs localization\n /**\n * PERIOD\n */\n PERIOD: 190,\n // needs localization\n /**\n * SLASH\n */\n SLASH: 191,\n // needs localization\n /**\n * APOSTROPHE\n */\n APOSTROPHE: 192,\n // needs localization\n /**\n * SINGLE_QUOTE\n */\n SINGLE_QUOTE: 222,\n // needs localization\n /**\n * OPEN_SQUARE_BRACKET\n */\n OPEN_SQUARE_BRACKET: 219,\n // needs localization\n /**\n * BACKSLASH\n */\n BACKSLASH: 220,\n // needs localization\n /**\n * CLOSE_SQUARE_BRACKET\n */\n CLOSE_SQUARE_BRACKET: 221,\n // needs localization\n /**\n * WIN_KEY\n */\n WIN_KEY: 224,\n /**\n * MAC_FF_META\n */\n MAC_FF_META: 224,\n // Firefox (Gecko) fires this for the meta key instead of 91\n /**\n * WIN_IME\n */\n WIN_IME: 229,\n // ======================== Function ========================\n /**\n * whether text and modified key is entered at the same time.\n */\n isTextModifyingKeyEvent: function isTextModifyingKeyEvent(e) {\n var keyCode = e.keyCode;\n if (e.altKey && !e.ctrlKey || e.metaKey ||\n // Function keys don\'t generate text\n keyCode >= KeyCode.F1 && keyCode <= KeyCode.F12) {\n return false;\n }\n\n // The following keys are quite harmless, even in combination with\n // CTRL, ALT or SHIFT.\n switch (keyCode) {\n case KeyCode.ALT:\n case KeyCode.CAPS_LOCK:\n case KeyCode.CONTEXT_MENU:\n case KeyCode.CTRL:\n case KeyCode.DOWN:\n case KeyCode.END:\n case KeyCode.ESC:\n case KeyCode.HOME:\n case KeyCode.INSERT:\n case KeyCode.LEFT:\n case KeyCode.MAC_FF_META:\n case KeyCode.META:\n case KeyCode.NUMLOCK:\n case KeyCode.NUM_CENTER:\n case KeyCode.PAGE_DOWN:\n case KeyCode.PAGE_UP:\n case KeyCode.PAUSE:\n case KeyCode.PRINT_SCREEN:\n case KeyCode.RIGHT:\n case KeyCode.SHIFT:\n case KeyCode.UP:\n case KeyCode.WIN_KEY:\n case KeyCode.WIN_KEY_RIGHT:\n return false;\n default:\n return true;\n }\n },\n /**\n * whether character is entered.\n */\n isCharacterKey: function isCharacterKey(keyCode) {\n if (keyCode >= KeyCode.ZERO && keyCode <= KeyCode.NINE) {\n return true;\n }\n if (keyCode >= KeyCode.NUM_ZERO && keyCode <= KeyCode.NUM_MULTIPLY) {\n return true;\n }\n if (keyCode >= KeyCode.A && keyCode <= KeyCode.Z) {\n return true;\n }\n\n // Safari sends zero key code for non-latin characters.\n if (window.navigator.userAgent.indexOf(\'WebKit\') !== -1 && keyCode === 0) {\n return true;\n }\n switch (keyCode) {\n case KeyCode.SPACE:\n case KeyCode.QUESTION_MARK:\n case KeyCode.NUM_PLUS:\n case KeyCode.NUM_MINUS:\n case KeyCode.NUM_PERIOD:\n case KeyCode.NUM_DIVISION:\n case KeyCode.SEMICOLON:\n case KeyCode.DASH:\n case KeyCode.EQUALS:\n case KeyCode.COMMA:\n case KeyCode.PERIOD:\n case KeyCode.SLASH:\n case KeyCode.APOSTROPHE:\n case KeyCode.SINGLE_QUOTE:\n case KeyCode.OPEN_SQUARE_BRACKET:\n case KeyCode.BACKSLASH:\n case KeyCode.CLOSE_SQUARE_BRACKET:\n return true;\n default:\n return false;\n }\n }\n};\n/* harmony default export */ const es_KeyCode = (KeyCode);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/context.js\n\nvar SliderContext = /*#__PURE__*/react.createContext({\n min: 0,\n max: 0,\n direction: \'ltr\',\n step: 1,\n includedStart: 0,\n includedEnd: 0,\n tabIndex: 0,\n keyboard: true\n});\n/* harmony default export */ const es_context = (SliderContext);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/util.js\nfunction getOffset(value, min, max) {\n return (value - min) / (max - min);\n}\nfunction getDirectionStyle(direction, value, min, max) {\n var offset = getOffset(value, min, max);\n var positionStyle = {};\n switch (direction) {\n case \'rtl\':\n positionStyle.right = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateX(50%)\';\n break;\n case \'btt\':\n positionStyle.bottom = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateY(50%)\';\n break;\n case \'ttb\':\n positionStyle.top = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateY(-50%)\';\n break;\n default:\n positionStyle.left = "".concat(offset * 100, "%");\n positionStyle.transform = \'translateX(-50%)\';\n break;\n }\n return positionStyle;\n}\n/** Return index value if is list or return value directly */\nfunction getIndex(value, index) {\n return Array.isArray(value) ? value[index] : value;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Handles/Handle.js\n\n\n\n\nvar _excluded = ["prefixCls", "value", "valueIndex", "onStartMove", "style", "render", "dragging", "onOffsetChange"];\n\n\n\n\n\nvar Handle = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _classNames, _getIndex;\n var prefixCls = props.prefixCls,\n value = props.value,\n valueIndex = props.valueIndex,\n onStartMove = props.onStartMove,\n style = props.style,\n render = props.render,\n dragging = props.dragging,\n onOffsetChange = props.onOffsetChange,\n restProps = objectWithoutProperties_objectWithoutProperties(props, _excluded);\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n disabled = _React$useContext.disabled,\n keyboard = _React$useContext.keyboard,\n range = _React$useContext.range,\n tabIndex = _React$useContext.tabIndex,\n ariaLabelForHandle = _React$useContext.ariaLabelForHandle,\n ariaLabelledByForHandle = _React$useContext.ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle = _React$useContext.ariaValueTextFormatterForHandle;\n var handlePrefixCls = "".concat(prefixCls, "-handle");\n // ============================ Events ============================\n var onInternalStartMove = function onInternalStartMove(e) {\n if (!disabled) {\n onStartMove(e, valueIndex);\n }\n };\n // =========================== Keyboard ===========================\n var onKeyDown = function onKeyDown(e) {\n if (!disabled && keyboard) {\n var offset = null;\n // Change the value\n switch (e.which || e.keyCode) {\n case es_KeyCode.LEFT:\n offset = direction === \'ltr\' || direction === \'btt\' ? -1 : 1;\n break;\n case es_KeyCode.RIGHT:\n offset = direction === \'ltr\' || direction === \'btt\' ? 1 : -1;\n break;\n // Up is plus\n case es_KeyCode.UP:\n offset = direction !== \'ttb\' ? 1 : -1;\n break;\n // Down is minus\n case es_KeyCode.DOWN:\n offset = direction !== \'ttb\' ? -1 : 1;\n break;\n case es_KeyCode.HOME:\n offset = \'min\';\n break;\n case es_KeyCode.END:\n offset = \'max\';\n break;\n case es_KeyCode.PAGE_UP:\n offset = 2;\n break;\n case es_KeyCode.PAGE_DOWN:\n offset = -2;\n break;\n }\n if (offset !== null) {\n e.preventDefault();\n onOffsetChange(offset, valueIndex);\n }\n }\n };\n // ============================ Offset ============================\n var positionStyle = getDirectionStyle(direction, value, min, max);\n // ============================ Render ============================\n var handleNode = /*#__PURE__*/react.createElement("div", extends_extends({\n ref: ref,\n className: classnames_default()(handlePrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(handlePrefixCls, "-").concat(valueIndex + 1), range), _defineProperty(_classNames, "".concat(handlePrefixCls, "-dragging"), dragging), _classNames)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: onInternalStartMove,\n onTouchStart: onInternalStartMove,\n onKeyDown: onKeyDown,\n tabIndex: disabled ? null : getIndex(tabIndex, valueIndex),\n role: "slider",\n "aria-valuemin": min,\n "aria-valuemax": max,\n "aria-valuenow": value,\n "aria-disabled": disabled,\n "aria-label": getIndex(ariaLabelForHandle, valueIndex),\n "aria-labelledby": getIndex(ariaLabelledByForHandle, valueIndex),\n "aria-valuetext": (_getIndex = getIndex(ariaValueTextFormatterForHandle, valueIndex)) === null || _getIndex === void 0 ? void 0 : _getIndex(value)\n }, restProps));\n // Customize\n if (render) {\n handleNode = render(handleNode, {\n index: valueIndex,\n prefixCls: prefixCls,\n value: value,\n dragging: dragging\n });\n }\n return handleNode;\n});\nif (false) {}\n/* harmony default export */ const Handles_Handle = (Handle);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Handles/index.js\n\n\nvar Handles_excluded = ["prefixCls", "style", "onStartMove", "onOffsetChange", "values", "handleRender", "draggingIndex"];\n\n\n\nvar Handles = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var prefixCls = props.prefixCls,\n style = props.style,\n onStartMove = props.onStartMove,\n onOffsetChange = props.onOffsetChange,\n values = props.values,\n handleRender = props.handleRender,\n draggingIndex = props.draggingIndex,\n restProps = objectWithoutProperties_objectWithoutProperties(props, Handles_excluded);\n var handlesRef = react.useRef({});\n react.useImperativeHandle(ref, function () {\n return {\n focus: function focus(index) {\n var _handlesRef$current$i;\n (_handlesRef$current$i = handlesRef.current[index]) === null || _handlesRef$current$i === void 0 ? void 0 : _handlesRef$current$i.focus();\n }\n };\n });\n return /*#__PURE__*/react.createElement(react.Fragment, null, values.map(function (value, index) {\n return /*#__PURE__*/react.createElement(Handles_Handle, extends_extends({\n ref: function ref(node) {\n if (!node) {\n delete handlesRef.current[index];\n } else {\n handlesRef.current[index] = node;\n }\n },\n dragging: draggingIndex === index,\n prefixCls: prefixCls,\n style: getIndex(style, index),\n key: index,\n value: value,\n valueIndex: index,\n onStartMove: onStartMove,\n onOffsetChange: onOffsetChange,\n render: handleRender\n }, restProps));\n }));\n});\nif (false) {}\n/* harmony default export */ const es_Handles = (Handles);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/hooks/useDrag.js\n\n\n\nfunction getPosition(e) {\n var obj = \'touches\' in e ? e.touches[0] : e;\n return {\n pageX: obj.pageX,\n pageY: obj.pageY\n };\n}\nfunction useDrag(containerRef, direction, rawValues, min, max, formatValue, triggerChange, finishChange, offsetValues) {\n var _React$useState = react.useState(null),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n draggingValue = _React$useState2[0],\n setDraggingValue = _React$useState2[1];\n var _React$useState3 = react.useState(-1),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n draggingIndex = _React$useState4[0],\n setDraggingIndex = _React$useState4[1];\n var _React$useState5 = react.useState(rawValues),\n _React$useState6 = slicedToArray_slicedToArray(_React$useState5, 2),\n cacheValues = _React$useState6[0],\n setCacheValues = _React$useState6[1];\n var _React$useState7 = react.useState(rawValues),\n _React$useState8 = slicedToArray_slicedToArray(_React$useState7, 2),\n originValues = _React$useState8[0],\n setOriginValues = _React$useState8[1];\n var mouseMoveEventRef = react.useRef(null);\n var mouseUpEventRef = react.useRef(null);\n react.useEffect(function () {\n if (draggingIndex === -1) {\n setCacheValues(rawValues);\n }\n }, [rawValues, draggingIndex]);\n // Clean up event\n react.useEffect(function () {\n return function () {\n document.removeEventListener(\'mousemove\', mouseMoveEventRef.current);\n document.removeEventListener(\'mouseup\', mouseUpEventRef.current);\n document.removeEventListener(\'touchmove\', mouseMoveEventRef.current);\n document.removeEventListener(\'touchend\', mouseUpEventRef.current);\n };\n }, []);\n var flushValues = function flushValues(nextValues, nextValue) {\n // Perf: Only update state when value changed\n if (cacheValues.some(function (val, i) {\n return val !== nextValues[i];\n })) {\n if (nextValue !== undefined) {\n setDraggingValue(nextValue);\n }\n setCacheValues(nextValues);\n triggerChange(nextValues);\n }\n };\n var updateCacheValue = function updateCacheValue(valueIndex, offsetPercent) {\n // Basic point offset\n if (valueIndex === -1) {\n // >>>> Dragging on the track\n var startValue = originValues[0];\n var endValue = originValues[originValues.length - 1];\n var maxStartOffset = min - startValue;\n var maxEndOffset = max - endValue;\n // Get valid offset\n var offset = offsetPercent * (max - min);\n offset = Math.max(offset, maxStartOffset);\n offset = Math.min(offset, maxEndOffset);\n // Use first value to revert back of valid offset (like steps marks)\n var formatStartValue = formatValue(startValue + offset);\n offset = formatStartValue - startValue;\n var cloneCacheValues = originValues.map(function (val) {\n return val + offset;\n });\n flushValues(cloneCacheValues);\n } else {\n // >>>> Dragging on the handle\n var offsetDist = (max - min) * offsetPercent;\n // Always start with the valueIndex origin value\n var cloneValues = _toConsumableArray(cacheValues);\n cloneValues[valueIndex] = originValues[valueIndex];\n var next = offsetValues(cloneValues, offsetDist, valueIndex, \'dist\');\n flushValues(next.values, next.value);\n }\n };\n // Resolve closure\n var updateCacheValueRef = react.useRef(updateCacheValue);\n updateCacheValueRef.current = updateCacheValue;\n var onStartMove = function onStartMove(e, valueIndex) {\n e.stopPropagation();\n var originValue = rawValues[valueIndex];\n setDraggingIndex(valueIndex);\n setDraggingValue(originValue);\n setOriginValues(rawValues);\n var _getPosition = getPosition(e),\n startX = _getPosition.pageX,\n startY = _getPosition.pageY;\n // Moving\n var onMouseMove = function onMouseMove(event) {\n event.preventDefault();\n var _getPosition2 = getPosition(event),\n moveX = _getPosition2.pageX,\n moveY = _getPosition2.pageY;\n var offsetX = moveX - startX;\n var offsetY = moveY - startY;\n var _containerRef$current = containerRef.current.getBoundingClientRect(),\n width = _containerRef$current.width,\n height = _containerRef$current.height;\n var offSetPercent;\n switch (direction) {\n case \'btt\':\n offSetPercent = -offsetY / height;\n break;\n case \'ttb\':\n offSetPercent = offsetY / height;\n break;\n case \'rtl\':\n offSetPercent = -offsetX / width;\n break;\n default:\n offSetPercent = offsetX / width;\n }\n updateCacheValueRef.current(valueIndex, offSetPercent);\n };\n // End\n var onMouseUp = function onMouseUp(event) {\n event.preventDefault();\n document.removeEventListener(\'mouseup\', onMouseUp);\n document.removeEventListener(\'mousemove\', onMouseMove);\n document.removeEventListener(\'touchend\', onMouseUp);\n document.removeEventListener(\'touchmove\', onMouseMove);\n mouseMoveEventRef.current = null;\n mouseUpEventRef.current = null;\n setDraggingIndex(-1);\n finishChange();\n };\n document.addEventListener(\'mouseup\', onMouseUp);\n document.addEventListener(\'mousemove\', onMouseMove);\n document.addEventListener(\'touchend\', onMouseUp);\n document.addEventListener(\'touchmove\', onMouseMove);\n mouseMoveEventRef.current = onMouseMove;\n mouseUpEventRef.current = onMouseUp;\n };\n // Only return cache value when it mapping with rawValues\n var returnValues = react.useMemo(function () {\n var sourceValues = _toConsumableArray(rawValues).sort(function (a, b) {\n return a - b;\n });\n var targetValues = _toConsumableArray(cacheValues).sort(function (a, b) {\n return a - b;\n });\n return sourceValues.every(function (val, index) {\n return val === targetValues[index];\n }) ? cacheValues : rawValues;\n }, [rawValues, cacheValues]);\n return [draggingIndex, draggingValue, returnValues, onStartMove];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Tracks/Track.js\n\n\n\n\n\nfunction Track(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n start = props.start,\n end = props.end,\n index = props.index,\n onStartMove = props.onStartMove;\n var _React$useContext = react.useContext(es_context),\n direction = _React$useContext.direction,\n min = _React$useContext.min,\n max = _React$useContext.max,\n disabled = _React$useContext.disabled,\n range = _React$useContext.range;\n var trackPrefixCls = "".concat(prefixCls, "-track");\n var offsetStart = getOffset(start, min, max);\n var offsetEnd = getOffset(end, min, max);\n // ============================ Events ============================\n var onInternalStartMove = function onInternalStartMove(e) {\n if (!disabled && onStartMove) {\n onStartMove(e, -1);\n }\n };\n // ============================ Render ============================\n var positionStyle = {};\n switch (direction) {\n case \'rtl\':\n positionStyle.right = "".concat(offsetStart * 100, "%");\n positionStyle.width = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n case \'btt\':\n positionStyle.bottom = "".concat(offsetStart * 100, "%");\n positionStyle.height = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n case \'ttb\':\n positionStyle.top = "".concat(offsetStart * 100, "%");\n positionStyle.height = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n break;\n default:\n positionStyle.left = "".concat(offsetStart * 100, "%");\n positionStyle.width = "".concat(offsetEnd * 100 - offsetStart * 100, "%");\n }\n return /*#__PURE__*/react.createElement("div", {\n className: classnames_default()(trackPrefixCls, range && "".concat(trackPrefixCls, "-").concat(index + 1)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: onInternalStartMove,\n onTouchStart: onInternalStartMove\n });\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Tracks/index.js\n\n\n\n\nfunction Tracks(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n values = props.values,\n startPoint = props.startPoint,\n onStartMove = props.onStartMove;\n var _React$useContext = react.useContext(es_context),\n included = _React$useContext.included,\n range = _React$useContext.range,\n min = _React$useContext.min;\n var trackList = react.useMemo(function () {\n if (!range) {\n // null value do not have track\n if (values.length === 0) {\n return [];\n }\n var startValue = startPoint !== null && startPoint !== void 0 ? startPoint : min;\n var endValue = values[0];\n return [{\n start: Math.min(startValue, endValue),\n end: Math.max(startValue, endValue)\n }];\n }\n // Multiple\n var list = [];\n for (var i = 0; i < values.length - 1; i += 1) {\n list.push({\n start: values[i],\n end: values[i + 1]\n });\n }\n return list;\n }, [values, range, startPoint, min]);\n return included ? trackList.map(function (_ref, index) {\n var start = _ref.start,\n end = _ref.end;\n return /*#__PURE__*/react.createElement(Track, {\n index: index,\n prefixCls: prefixCls,\n style: getIndex(style, index),\n start: start,\n end: end,\n key: index,\n onStartMove: onStartMove\n });\n }) : null;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Marks/Mark.js\n\n\n\n\n\n\nfunction Mark(props) {\n var prefixCls = props.prefixCls,\n style = props.style,\n children = props.children,\n value = props.value,\n _onClick = props.onClick;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n includedStart = _React$useContext.includedStart,\n includedEnd = _React$useContext.includedEnd,\n included = _React$useContext.included;\n var textCls = "".concat(prefixCls, "-text");\n // ============================ Offset ============================\n var positionStyle = getDirectionStyle(direction, value, min, max);\n return /*#__PURE__*/react.createElement("span", {\n className: classnames_default()(textCls, _defineProperty({}, "".concat(textCls, "-active"), included && includedStart <= value && value <= includedEnd)),\n style: _objectSpread2(_objectSpread2({}, positionStyle), style),\n onMouseDown: function onMouseDown(e) {\n e.stopPropagation();\n },\n onClick: function onClick() {\n _onClick(value);\n }\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Marks/index.js\n\n\nfunction Marks(props) {\n var prefixCls = props.prefixCls,\n marks = props.marks,\n onClick = props.onClick;\n var markPrefixCls = "".concat(prefixCls, "-mark");\n // Not render mark if empty\n if (!marks.length) {\n return null;\n }\n return /*#__PURE__*/react.createElement("div", {\n className: markPrefixCls\n }, marks.map(function (_ref) {\n var value = _ref.value,\n style = _ref.style,\n label = _ref.label;\n return /*#__PURE__*/react.createElement(Mark, {\n key: value,\n prefixCls: markPrefixCls,\n style: style,\n value: value,\n onClick: onClick\n }, label);\n }));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Steps/Dot.js\n\n\n\n\n\n\nfunction Dot(props) {\n var prefixCls = props.prefixCls,\n value = props.value,\n style = props.style,\n activeStyle = props.activeStyle;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n direction = _React$useContext.direction,\n included = _React$useContext.included,\n includedStart = _React$useContext.includedStart,\n includedEnd = _React$useContext.includedEnd;\n var dotClassName = "".concat(prefixCls, "-dot");\n var active = included && includedStart <= value && value <= includedEnd;\n // ============================ Offset ============================\n var mergedStyle = _objectSpread2(_objectSpread2({}, getDirectionStyle(direction, value, min, max)), typeof style === \'function\' ? style(value) : style);\n if (active) {\n mergedStyle = _objectSpread2(_objectSpread2({}, mergedStyle), typeof activeStyle === \'function\' ? activeStyle(value) : activeStyle);\n }\n return /*#__PURE__*/react.createElement("span", {\n className: classnames_default()(dotClassName, _defineProperty({}, "".concat(dotClassName, "-active"), active)),\n style: mergedStyle\n });\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Steps/index.js\n\n\n\nfunction Steps(props) {\n var prefixCls = props.prefixCls,\n marks = props.marks,\n dots = props.dots,\n style = props.style,\n activeStyle = props.activeStyle;\n var _React$useContext = react.useContext(es_context),\n min = _React$useContext.min,\n max = _React$useContext.max,\n step = _React$useContext.step;\n var stepDots = react.useMemo(function () {\n var dotSet = new Set();\n // Add marks\n marks.forEach(function (mark) {\n dotSet.add(mark.value);\n });\n // Fill dots\n if (dots && step !== null) {\n var current = min;\n while (current <= max) {\n dotSet.add(current);\n current += step;\n }\n }\n return Array.from(dotSet);\n }, [min, max, step, dots, marks]);\n return /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-step")\n }, stepDots.map(function (dotValue) {\n return /*#__PURE__*/react.createElement(Dot, {\n prefixCls: prefixCls,\n key: dotValue,\n value: dotValue,\n style: style,\n activeStyle: activeStyle\n });\n }));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/hooks/useOffset.js\n\n\nfunction useOffset(min, max, step, markList, allowCross, pushable) {\n var formatRangeValue = react.useCallback(function (val) {\n var formatNextValue = isFinite(val) ? val : min;\n formatNextValue = Math.min(max, val);\n formatNextValue = Math.max(min, formatNextValue);\n return formatNextValue;\n }, [min, max]);\n var formatStepValue = react.useCallback(function (val) {\n if (step !== null) {\n var stepValue = min + Math.round((formatRangeValue(val) - min) / step) * step;\n // Cut number in case to be like 0.30000000000000004\n var getDecimal = function getDecimal(num) {\n return (String(num).split(\'.\')[1] || \'\').length;\n };\n var maxDecimal = Math.max(getDecimal(step), getDecimal(max), getDecimal(min));\n var fixedValue = Number(stepValue.toFixed(maxDecimal));\n return min <= fixedValue && fixedValue <= max ? fixedValue : null;\n }\n return null;\n }, [step, min, max, formatRangeValue]);\n var formatValue = react.useCallback(function (val) {\n var formatNextValue = formatRangeValue(val);\n // List align values\n var alignValues = markList.map(function (mark) {\n return mark.value;\n });\n if (step !== null) {\n alignValues.push(formatStepValue(val));\n }\n // min & max\n alignValues.push(min, max);\n // Align with marks\n var closeValue = alignValues[0];\n var closeDist = max - min;\n alignValues.forEach(function (alignValue) {\n var dist = Math.abs(formatNextValue - alignValue);\n if (dist <= closeDist) {\n closeValue = alignValue;\n closeDist = dist;\n }\n });\n return closeValue;\n }, [min, max, markList, step, formatRangeValue, formatStepValue]);\n // ========================== Offset ==========================\n // Single Value\n var offsetValue = function offsetValue(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n if (typeof offset === \'number\') {\n var nextValue;\n var originValue = values[valueIndex];\n // Only used for `dist` mode\n var targetDistValue = originValue + offset;\n // Compare next step value & mark value which is best match\n var potentialValues = [];\n markList.forEach(function (mark) {\n potentialValues.push(mark.value);\n });\n // Min & Max\n potentialValues.push(min, max);\n // In case origin value is align with mark but not with step\n potentialValues.push(formatStepValue(originValue));\n // Put offset step value also\n var sign = offset > 0 ? 1 : -1;\n if (mode === \'unit\') {\n potentialValues.push(formatStepValue(originValue + sign * step));\n } else {\n potentialValues.push(formatStepValue(targetDistValue));\n }\n // Find close one\n potentialValues = potentialValues.filter(function (val) {\n return val !== null;\n })\n // Remove reverse value\n .filter(function (val) {\n return offset < 0 ? val <= originValue : val >= originValue;\n });\n if (mode === \'unit\') {\n // `unit` mode can not contain itself\n potentialValues = potentialValues.filter(function (val) {\n return val !== originValue;\n });\n }\n var compareValue = mode === \'unit\' ? originValue : targetDistValue;\n nextValue = potentialValues[0];\n var valueDist = Math.abs(nextValue - compareValue);\n potentialValues.forEach(function (potentialValue) {\n var dist = Math.abs(potentialValue - compareValue);\n if (dist < valueDist) {\n nextValue = potentialValue;\n valueDist = dist;\n }\n });\n // Out of range will back to range\n if (nextValue === undefined) {\n return offset < 0 ? min : max;\n }\n // `dist` mode\n if (mode === \'dist\') {\n return nextValue;\n }\n // `unit` mode may need another round\n if (Math.abs(offset) > 1) {\n var cloneValues = _toConsumableArray(values);\n cloneValues[valueIndex] = nextValue;\n return offsetValue(cloneValues, offset - sign, valueIndex, mode);\n }\n return nextValue;\n } else if (offset === \'min\') {\n return min;\n } else if (offset === \'max\') {\n return max;\n }\n };\n /** Same as `offsetValue` but return `changed` mark to tell value changed */\n var offsetChangedValue = function offsetChangedValue(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n var originValue = values[valueIndex];\n var nextValue = offsetValue(values, offset, valueIndex, mode);\n return {\n value: nextValue,\n changed: nextValue !== originValue\n };\n };\n var needPush = function needPush(dist) {\n return pushable === null && dist === 0 || typeof pushable === \'number\' && dist < pushable;\n };\n // Values\n var offsetValues = function offsetValues(values, offset, valueIndex) {\n var mode = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : \'unit\';\n var nextValues = values.map(formatValue);\n var originValue = nextValues[valueIndex];\n var nextValue = offsetValue(nextValues, offset, valueIndex, mode);\n nextValues[valueIndex] = nextValue;\n if (allowCross === false) {\n // >>>>> Allow Cross\n var pushNum = pushable || 0;\n // ============ AllowCross ===============\n if (valueIndex > 0 && nextValues[valueIndex - 1] !== originValue) {\n nextValues[valueIndex] = Math.max(nextValues[valueIndex], nextValues[valueIndex - 1] + pushNum);\n }\n if (valueIndex < nextValues.length - 1 && nextValues[valueIndex + 1] !== originValue) {\n nextValues[valueIndex] = Math.min(nextValues[valueIndex], nextValues[valueIndex + 1] - pushNum);\n }\n } else if (typeof pushable === \'number\' || pushable === null) {\n // >>>>> Pushable\n // =============== Push ==================\n // >>>>>> Basic push\n // End values\n for (var i = valueIndex + 1; i < nextValues.length; i += 1) {\n var changed = true;\n while (needPush(nextValues[i] - nextValues[i - 1]) && changed) {\n var _offsetChangedValue = offsetChangedValue(nextValues, 1, i);\n nextValues[i] = _offsetChangedValue.value;\n changed = _offsetChangedValue.changed;\n }\n }\n // Start values\n for (var _i = valueIndex; _i > 0; _i -= 1) {\n var _changed = true;\n while (needPush(nextValues[_i] - nextValues[_i - 1]) && _changed) {\n var _offsetChangedValue2 = offsetChangedValue(nextValues, -1, _i - 1);\n nextValues[_i - 1] = _offsetChangedValue2.value;\n _changed = _offsetChangedValue2.changed;\n }\n }\n // >>>>> Revert back to safe push range\n // End to Start\n for (var _i2 = nextValues.length - 1; _i2 > 0; _i2 -= 1) {\n var _changed2 = true;\n while (needPush(nextValues[_i2] - nextValues[_i2 - 1]) && _changed2) {\n var _offsetChangedValue3 = offsetChangedValue(nextValues, -1, _i2 - 1);\n nextValues[_i2 - 1] = _offsetChangedValue3.value;\n _changed2 = _offsetChangedValue3.changed;\n }\n }\n // Start to End\n for (var _i3 = 0; _i3 < nextValues.length - 1; _i3 += 1) {\n var _changed3 = true;\n while (needPush(nextValues[_i3 + 1] - nextValues[_i3]) && _changed3) {\n var _offsetChangedValue4 = offsetChangedValue(nextValues, 1, _i3 + 1);\n nextValues[_i3 + 1] = _offsetChangedValue4.value;\n _changed3 = _offsetChangedValue4.changed;\n }\n }\n }\n return {\n value: nextValues[valueIndex],\n values: nextValues\n };\n };\n return [formatValue, offsetValues];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/Slider.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar Slider = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _classNames;\n var _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-slider\' : _props$prefixCls,\n className = props.className,\n style = props.style,\n _props$disabled = props.disabled,\n disabled = _props$disabled === void 0 ? false : _props$disabled,\n _props$keyboard = props.keyboard,\n keyboard = _props$keyboard === void 0 ? true : _props$keyboard,\n autoFocus = props.autoFocus,\n onFocus = props.onFocus,\n onBlur = props.onBlur,\n _props$min = props.min,\n min = _props$min === void 0 ? 0 : _props$min,\n _props$max = props.max,\n max = _props$max === void 0 ? 100 : _props$max,\n _props$step = props.step,\n step = _props$step === void 0 ? 1 : _props$step,\n value = props.value,\n defaultValue = props.defaultValue,\n range = props.range,\n count = props.count,\n onChange = props.onChange,\n onBeforeChange = props.onBeforeChange,\n onAfterChange = props.onAfterChange,\n _props$allowCross = props.allowCross,\n allowCross = _props$allowCross === void 0 ? true : _props$allowCross,\n _props$pushable = props.pushable,\n pushable = _props$pushable === void 0 ? false : _props$pushable,\n draggableTrack = props.draggableTrack,\n reverse = props.reverse,\n vertical = props.vertical,\n _props$included = props.included,\n included = _props$included === void 0 ? true : _props$included,\n startPoint = props.startPoint,\n trackStyle = props.trackStyle,\n handleStyle = props.handleStyle,\n railStyle = props.railStyle,\n dotStyle = props.dotStyle,\n activeDotStyle = props.activeDotStyle,\n marks = props.marks,\n dots = props.dots,\n handleRender = props.handleRender,\n _props$tabIndex = props.tabIndex,\n tabIndex = _props$tabIndex === void 0 ? 0 : _props$tabIndex,\n ariaLabelForHandle = props.ariaLabelForHandle,\n ariaLabelledByForHandle = props.ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle = props.ariaValueTextFormatterForHandle;\n var handlesRef = react.useRef();\n var containerRef = react.useRef();\n var direction = react.useMemo(function () {\n if (vertical) {\n return reverse ? \'ttb\' : \'btt\';\n }\n return reverse ? \'rtl\' : \'ltr\';\n }, [reverse, vertical]);\n // ============================ Range =============================\n var mergedMin = react.useMemo(function () {\n return isFinite(min) ? min : 0;\n }, [min]);\n var mergedMax = react.useMemo(function () {\n return isFinite(max) ? max : 100;\n }, [max]);\n // ============================= Step =============================\n var mergedStep = react.useMemo(function () {\n return step !== null && step <= 0 ? 1 : step;\n }, [step]);\n // ============================= Push =============================\n var mergedPush = react.useMemo(function () {\n if (pushable === true) {\n return mergedStep;\n }\n return pushable >= 0 ? pushable : false;\n }, [pushable, mergedStep]);\n // ============================ Marks =============================\n var markList = react.useMemo(function () {\n var keys = Object.keys(marks || {});\n return keys.map(function (key) {\n var mark = marks[key];\n var markObj = {\n value: Number(key)\n };\n if (mark && typeof_typeof(mark) === \'object\' && ! /*#__PURE__*/react.isValidElement(mark) && (\'label\' in mark || \'style\' in mark)) {\n markObj.style = mark.style;\n markObj.label = mark.label;\n } else {\n markObj.label = mark;\n }\n return markObj;\n }).filter(function (_ref) {\n var label = _ref.label;\n return label || typeof label === \'number\';\n }).sort(function (a, b) {\n return a.value - b.value;\n });\n }, [marks]);\n // ============================ Format ============================\n var _useOffset = useOffset(mergedMin, mergedMax, mergedStep, markList, allowCross, mergedPush),\n _useOffset2 = slicedToArray_slicedToArray(_useOffset, 2),\n formatValue = _useOffset2[0],\n offsetValues = _useOffset2[1];\n // ============================ Values ============================\n var _useMergedState = useMergedState(defaultValue, {\n value: value\n }),\n _useMergedState2 = slicedToArray_slicedToArray(_useMergedState, 2),\n mergedValue = _useMergedState2[0],\n setValue = _useMergedState2[1];\n var rawValues = react.useMemo(function () {\n var valueList = mergedValue === null || mergedValue === undefined ? [] : Array.isArray(mergedValue) ? mergedValue : [mergedValue];\n var _valueList = slicedToArray_slicedToArray(valueList, 1),\n _valueList$ = _valueList[0],\n val0 = _valueList$ === void 0 ? mergedMin : _valueList$;\n var returnValues = mergedValue === null ? [] : [val0];\n // Format as range\n if (range) {\n returnValues = _toConsumableArray(valueList);\n // When count provided or value is `undefined`, we fill values\n if (count || mergedValue === undefined) {\n var pointCount = count >= 0 ? count + 1 : 2;\n returnValues = returnValues.slice(0, pointCount);\n // Fill with count\n while (returnValues.length < pointCount) {\n var _returnValues;\n returnValues.push((_returnValues = returnValues[returnValues.length - 1]) !== null && _returnValues !== void 0 ? _returnValues : mergedMin);\n }\n }\n returnValues.sort(function (a, b) {\n return a - b;\n });\n }\n // Align in range\n returnValues.forEach(function (val, index) {\n returnValues[index] = formatValue(val);\n });\n return returnValues;\n }, [mergedValue, range, mergedMin, count, formatValue]);\n // =========================== onChange ===========================\n var rawValuesRef = react.useRef(rawValues);\n rawValuesRef.current = rawValues;\n var getTriggerValue = function getTriggerValue(triggerValues) {\n return range ? triggerValues : triggerValues[0];\n };\n var triggerChange = function triggerChange(nextValues) {\n // Order first\n var cloneNextValues = _toConsumableArray(nextValues).sort(function (a, b) {\n return a - b;\n });\n // Trigger event if needed\n if (onChange && !es_isEqual(cloneNextValues, rawValuesRef.current, true)) {\n onChange(getTriggerValue(cloneNextValues));\n }\n // We set this later since it will re-render component immediately\n setValue(cloneNextValues);\n };\n var changeToCloseValue = function changeToCloseValue(newValue) {\n if (!disabled) {\n var valueIndex = 0;\n var valueDist = mergedMax - mergedMin;\n rawValues.forEach(function (val, index) {\n var dist = Math.abs(newValue - val);\n if (dist <= valueDist) {\n valueDist = dist;\n valueIndex = index;\n }\n });\n // Create new values\n var cloneNextValues = _toConsumableArray(rawValues);\n cloneNextValues[valueIndex] = newValue;\n // Fill value to match default 2\n if (range && !rawValues.length && count === undefined) {\n cloneNextValues.push(newValue);\n }\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(cloneNextValues));\n triggerChange(cloneNextValues);\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(cloneNextValues));\n }\n };\n // ============================ Click =============================\n var onSliderMouseDown = function onSliderMouseDown(e) {\n e.preventDefault();\n var _containerRef$current = containerRef.current.getBoundingClientRect(),\n width = _containerRef$current.width,\n height = _containerRef$current.height,\n left = _containerRef$current.left,\n top = _containerRef$current.top,\n bottom = _containerRef$current.bottom,\n right = _containerRef$current.right;\n var clientX = e.clientX,\n clientY = e.clientY;\n var percent;\n switch (direction) {\n case \'btt\':\n percent = (bottom - clientY) / height;\n break;\n case \'ttb\':\n percent = (clientY - top) / height;\n break;\n case \'rtl\':\n percent = (right - clientX) / width;\n break;\n default:\n percent = (clientX - left) / width;\n }\n var nextValue = mergedMin + percent * (mergedMax - mergedMin);\n changeToCloseValue(formatValue(nextValue));\n };\n // =========================== Keyboard ===========================\n var _React$useState = react.useState(null),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n keyboardValue = _React$useState2[0],\n setKeyboardValue = _React$useState2[1];\n var onHandleOffsetChange = function onHandleOffsetChange(offset, valueIndex) {\n if (!disabled) {\n var next = offsetValues(rawValues, offset, valueIndex);\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(rawValues));\n triggerChange(next.values);\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(next.values));\n setKeyboardValue(next.value);\n }\n };\n react.useEffect(function () {\n if (keyboardValue !== null) {\n var valueIndex = rawValues.indexOf(keyboardValue);\n if (valueIndex >= 0) {\n handlesRef.current.focus(valueIndex);\n }\n }\n setKeyboardValue(null);\n }, [keyboardValue]);\n // ============================= Drag =============================\n var mergedDraggableTrack = react.useMemo(function () {\n if (draggableTrack && mergedStep === null) {\n if (false) {}\n return false;\n }\n return draggableTrack;\n }, [draggableTrack, mergedStep]);\n var finishChange = function finishChange() {\n onAfterChange === null || onAfterChange === void 0 ? void 0 : onAfterChange(getTriggerValue(rawValuesRef.current));\n };\n var _useDrag = useDrag(containerRef, direction, rawValues, mergedMin, mergedMax, formatValue, triggerChange, finishChange, offsetValues),\n _useDrag2 = slicedToArray_slicedToArray(_useDrag, 4),\n draggingIndex = _useDrag2[0],\n draggingValue = _useDrag2[1],\n cacheValues = _useDrag2[2],\n onStartDrag = _useDrag2[3];\n var onStartMove = function onStartMove(e, valueIndex) {\n onStartDrag(e, valueIndex);\n onBeforeChange === null || onBeforeChange === void 0 ? void 0 : onBeforeChange(getTriggerValue(rawValuesRef.current));\n };\n // Auto focus for updated handle\n var dragging = draggingIndex !== -1;\n react.useEffect(function () {\n if (!dragging) {\n var valueIndex = rawValues.lastIndexOf(draggingValue);\n handlesRef.current.focus(valueIndex);\n }\n }, [dragging]);\n // =========================== Included ===========================\n var sortedCacheValues = react.useMemo(function () {\n return _toConsumableArray(cacheValues).sort(function (a, b) {\n return a - b;\n });\n }, [cacheValues]);\n // Provide a range values with included [min, max]\n // Used for Track, Mark & Dot\n var _React$useMemo = react.useMemo(function () {\n if (!range) {\n return [mergedMin, sortedCacheValues[0]];\n }\n return [sortedCacheValues[0], sortedCacheValues[sortedCacheValues.length - 1]];\n }, [sortedCacheValues, range, mergedMin]),\n _React$useMemo2 = slicedToArray_slicedToArray(_React$useMemo, 2),\n includedStart = _React$useMemo2[0],\n includedEnd = _React$useMemo2[1];\n // ============================= Refs =============================\n react.useImperativeHandle(ref, function () {\n return {\n focus: function focus() {\n handlesRef.current.focus(0);\n },\n blur: function blur() {\n var _document = document,\n activeElement = _document.activeElement;\n if (containerRef.current.contains(activeElement)) {\n activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur();\n }\n }\n };\n });\n // ========================== Auto Focus ==========================\n react.useEffect(function () {\n if (autoFocus) {\n handlesRef.current.focus(0);\n }\n }, []);\n // =========================== Context ============================\n var context = react.useMemo(function () {\n return {\n min: mergedMin,\n max: mergedMax,\n direction: direction,\n disabled: disabled,\n keyboard: keyboard,\n step: mergedStep,\n included: included,\n includedStart: includedStart,\n includedEnd: includedEnd,\n range: range,\n tabIndex: tabIndex,\n ariaLabelForHandle: ariaLabelForHandle,\n ariaLabelledByForHandle: ariaLabelledByForHandle,\n ariaValueTextFormatterForHandle: ariaValueTextFormatterForHandle\n };\n }, [mergedMin, mergedMax, direction, disabled, keyboard, mergedStep, included, includedStart, includedEnd, range, tabIndex, ariaLabelForHandle, ariaLabelledByForHandle, ariaValueTextFormatterForHandle]);\n // ============================ Render ============================\n return /*#__PURE__*/react.createElement(es_context.Provider, {\n value: context\n }, /*#__PURE__*/react.createElement("div", {\n ref: containerRef,\n className: classnames_default()(prefixCls, className, (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames, "".concat(prefixCls, "-vertical"), vertical), _defineProperty(_classNames, "".concat(prefixCls, "-horizontal"), !vertical), _defineProperty(_classNames, "".concat(prefixCls, "-with-marks"), markList.length), _classNames)),\n style: style,\n onMouseDown: onSliderMouseDown\n }, /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-rail"),\n style: railStyle\n }), /*#__PURE__*/react.createElement(Tracks, {\n prefixCls: prefixCls,\n style: trackStyle,\n values: sortedCacheValues,\n startPoint: startPoint,\n onStartMove: mergedDraggableTrack ? onStartMove : null\n }), /*#__PURE__*/react.createElement(Steps, {\n prefixCls: prefixCls,\n marks: markList,\n dots: dots,\n style: dotStyle,\n activeStyle: activeDotStyle\n }), /*#__PURE__*/react.createElement(es_Handles, {\n ref: handlesRef,\n prefixCls: prefixCls,\n style: handleStyle,\n values: cacheValues,\n draggingIndex: draggingIndex,\n onStartMove: onStartMove,\n onOffsetChange: onHandleOffsetChange,\n onFocus: onFocus,\n onBlur: onBlur,\n handleRender: handleRender\n }), /*#__PURE__*/react.createElement(Marks, {\n prefixCls: prefixCls,\n marks: markList,\n onClick: changeToCloseValue\n })));\n});\nif (false) {}\n/* harmony default export */ const es_Slider = (Slider);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/es/index.js\n\n/* harmony default export */ const es = (es_Slider);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\nvar injectStylesIntoStyleTag = __webpack_require__(379);\nvar injectStylesIntoStyleTag_default = /*#__PURE__*/__webpack_require__.n(injectStylesIntoStyleTag);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleDomAPI.js\nvar styleDomAPI = __webpack_require__(795);\nvar styleDomAPI_default = /*#__PURE__*/__webpack_require__.n(styleDomAPI);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertBySelector.js\nvar insertBySelector = __webpack_require__(569);\nvar insertBySelector_default = /*#__PURE__*/__webpack_require__.n(insertBySelector);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\nvar setAttributesWithoutAttributes = __webpack_require__(565);\nvar setAttributesWithoutAttributes_default = /*#__PURE__*/__webpack_require__.n(setAttributesWithoutAttributes);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/insertStyleElement.js\nvar insertStyleElement = __webpack_require__(216);\nvar insertStyleElement_default = /*#__PURE__*/__webpack_require__.n(insertStyleElement);\n// EXTERNAL MODULE: ./node_modules/style-loader/dist/runtime/styleTagTransform.js\nvar styleTagTransform = __webpack_require__(589);\nvar styleTagTransform_default = /*#__PURE__*/__webpack_require__.n(styleTagTransform);\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./node_modules/rc-tooltip/assets/bootstrap.css\nvar bootstrap = __webpack_require__(467);\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/assets/bootstrap.css\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (styleTagTransform_default());\noptions.setAttributes = (setAttributesWithoutAttributes_default());\n\n options.insert = insertBySelector_default().bind(null, "head");\n \noptions.domAPI = (styleDomAPI_default());\noptions.insertStyleElement = (insertStyleElement_default());\n\nvar update = injectStylesIntoStyleTag_default()(bootstrap/* default */.Z, options);\n\n\n\n\n /* harmony default export */ const assets_bootstrap = (bootstrap/* default */.Z && bootstrap/* default.locals */.Z.locals ? bootstrap/* default.locals */.Z.locals : undefined);\n\n// EXTERNAL MODULE: ./node_modules/rc-util/lib/raf.js\nvar raf = __webpack_require__(543);\n// EXTERNAL MODULE: ./node_modules/react-dom/index.js\nvar react_dom = __webpack_require__(935);\n// EXTERNAL MODULE: ./node_modules/react-is/index.js\nvar react_is = __webpack_require__(864);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useMemo.js\n\nfunction useMemo(getValue, condition, shouldUpdate) {\n var cacheRef = react.useRef({});\n if (!(\'value\' in cacheRef.current) || shouldUpdate(cacheRef.current.condition, condition)) {\n cacheRef.current.value = getValue();\n cacheRef.current.condition = condition;\n }\n return cacheRef.current.value;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/ref.js\n\n/* eslint-disable no-param-reassign */\n\n\n\nfunction fillRef(ref, node) {\n if (typeof ref === \'function\') {\n ref(node);\n } else if (typeof_typeof(ref) === \'object\' && ref && \'current\' in ref) {\n ref.current = node;\n }\n}\n\n/**\n * Merge refs into one ref function to support ref passing.\n */\nfunction composeRef() {\n for (var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++) {\n refs[_key] = arguments[_key];\n }\n var refList = refs.filter(function (ref) {\n return ref;\n });\n if (refList.length <= 1) {\n return refList[0];\n }\n return function (node) {\n refs.forEach(function (ref) {\n fillRef(ref, node);\n });\n };\n}\nfunction useComposeRef() {\n for (var _len2 = arguments.length, refs = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n refs[_key2] = arguments[_key2];\n }\n return useMemo(function () {\n return composeRef.apply(void 0, refs);\n }, refs, function (prev, next) {\n return prev.length === next.length && prev.every(function (ref, i) {\n return ref === next[i];\n });\n });\n}\nfunction supportRef(nodeOrComponent) {\n var _type$prototype, _nodeOrComponent$prot;\n var type = (0,react_is.isMemo)(nodeOrComponent) ? nodeOrComponent.type.type : nodeOrComponent.type;\n\n // Function component node\n if (typeof type === \'function\' && !((_type$prototype = type.prototype) !== null && _type$prototype !== void 0 && _type$prototype.render)) {\n return false;\n }\n\n // Class component\n if (typeof nodeOrComponent === \'function\' && !((_nodeOrComponent$prot = nodeOrComponent.prototype) !== null && _nodeOrComponent$prot !== void 0 && _nodeOrComponent$prot.render)) {\n return false;\n }\n return true;\n}\n/* eslint-enable */\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/Context.js\n\nvar OrderContext = /*#__PURE__*/react.createContext(null);\n/* harmony default export */ const es_Context = (OrderContext);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/useDom.js\n\n\n\n\n\n\nvar EMPTY_LIST = [];\n\n/**\n * Will add `div` to document. Nest call will keep order\n * @param render Render DOM in document\n */\nfunction useDom(render, debug) {\n var _React$useState = react.useState(function () {\n if (!canUseDom()) {\n return null;\n }\n var defaultEle = document.createElement(\'div\');\n if (false) {}\n return defaultEle;\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 1),\n ele = _React$useState2[0];\n\n // ========================== Order ==========================\n var appendedRef = react.useRef(false);\n var queueCreate = react.useContext(es_Context);\n var _React$useState3 = react.useState(EMPTY_LIST),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n queue = _React$useState4[0],\n setQueue = _React$useState4[1];\n var mergedQueueCreate = queueCreate || (appendedRef.current ? undefined : function (appendFn) {\n setQueue(function (origin) {\n var newQueue = [appendFn].concat(_toConsumableArray(origin));\n return newQueue;\n });\n });\n\n // =========================== DOM ===========================\n function append() {\n if (!ele.parentElement) {\n document.body.appendChild(ele);\n }\n appendedRef.current = true;\n }\n function cleanup() {\n var _ele$parentElement;\n (_ele$parentElement = ele.parentElement) === null || _ele$parentElement === void 0 ? void 0 : _ele$parentElement.removeChild(ele);\n appendedRef.current = false;\n }\n hooks_useLayoutEffect(function () {\n if (render) {\n if (queueCreate) {\n queueCreate(append);\n } else {\n append();\n }\n } else {\n cleanup();\n }\n return cleanup;\n }, [render]);\n hooks_useLayoutEffect(function () {\n if (queue.length) {\n queue.forEach(function (appendFn) {\n return appendFn();\n });\n setQueue(EMPTY_LIST);\n }\n }, [queue]);\n return [ele, mergedQueueCreate];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/contains.js\nfunction contains(root, n) {\n if (!root) {\n return false;\n }\n\n // Use native if support\n if (root.contains) {\n return root.contains(n);\n }\n\n // `document.contains` not support with IE11\n var node = n;\n while (node) {\n if (node === root) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/dynamicCSS.js\n\n\nvar APPEND_ORDER = \'data-rc-order\';\nvar MARK_KEY = "rc-util-key";\nvar containerCache = new Map();\nfunction getMark() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n mark = _ref.mark;\n if (mark) {\n return mark.startsWith(\'data-\') ? mark : "data-".concat(mark);\n }\n return MARK_KEY;\n}\nfunction getContainer(option) {\n if (option.attachTo) {\n return option.attachTo;\n }\n var head = document.querySelector(\'head\');\n return head || document.body;\n}\nfunction getOrder(prepend) {\n if (prepend === \'queue\') {\n return \'prependQueue\';\n }\n return prepend ? \'prepend\' : \'append\';\n}\n\n/**\n * Find style which inject by rc-util\n */\nfunction findStyles(container) {\n return Array.from((containerCache.get(container) || container).children).filter(function (node) {\n return node.tagName === \'STYLE\';\n });\n}\nfunction injectCSS(css) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n if (!canUseDom()) {\n return null;\n }\n var csp = option.csp,\n prepend = option.prepend;\n var styleNode = document.createElement(\'style\');\n styleNode.setAttribute(APPEND_ORDER, getOrder(prepend));\n if (csp !== null && csp !== void 0 && csp.nonce) {\n styleNode.nonce = csp === null || csp === void 0 ? void 0 : csp.nonce;\n }\n styleNode.innerHTML = css;\n var container = getContainer(option);\n var firstChild = container.firstChild;\n if (prepend) {\n // If is queue `prepend`, it will prepend first style and then append rest style\n if (prepend === \'queue\') {\n var existStyle = findStyles(container).filter(function (node) {\n return [\'prepend\', \'prependQueue\'].includes(node.getAttribute(APPEND_ORDER));\n });\n if (existStyle.length) {\n container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling);\n return styleNode;\n }\n }\n\n // Use `insertBefore` as `prepend`\n container.insertBefore(styleNode, firstChild);\n } else {\n container.appendChild(styleNode);\n }\n return styleNode;\n}\nfunction findExistNode(key) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var container = getContainer(option);\n return findStyles(container).find(function (node) {\n return node.getAttribute(getMark(option)) === key;\n });\n}\nfunction removeCSS(key) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var existNode = findExistNode(key, option);\n if (existNode) {\n var container = getContainer(option);\n container.removeChild(existNode);\n }\n}\n\n/**\n * qiankun will inject `appendChild` to insert into other\n */\nfunction syncRealContainer(container, option) {\n var cachedRealContainer = containerCache.get(container);\n\n // Find real container when not cached or cached container removed\n if (!cachedRealContainer || !contains(document, cachedRealContainer)) {\n var placeholderStyle = injectCSS(\'\', option);\n var parentNode = placeholderStyle.parentNode;\n containerCache.set(container, parentNode);\n container.removeChild(placeholderStyle);\n }\n}\n\n/**\n * manually clear container cache to avoid global cache in unit testes\n */\nfunction clearContainerCache() {\n containerCache.clear();\n}\nfunction updateCSS(css, key) {\n var option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var container = getContainer(option);\n\n // Sync real parent\n syncRealContainer(container, option);\n var existNode = findExistNode(key, option);\n if (existNode) {\n var _option$csp, _option$csp2;\n if ((_option$csp = option.csp) !== null && _option$csp !== void 0 && _option$csp.nonce && existNode.nonce !== ((_option$csp2 = option.csp) === null || _option$csp2 === void 0 ? void 0 : _option$csp2.nonce)) {\n var _option$csp3;\n existNode.nonce = (_option$csp3 = option.csp) === null || _option$csp3 === void 0 ? void 0 : _option$csp3.nonce;\n }\n if (existNode.innerHTML !== css) {\n existNode.innerHTML = css;\n }\n return existNode;\n }\n var newNode = injectCSS(css, option);\n newNode.setAttribute(getMark(option), key);\n return newNode;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/getScrollBarSize.js\n/* eslint-disable no-param-reassign */\n\nvar cached;\nfunction getScrollBarSize(fresh) {\n if (typeof document === \'undefined\') {\n return 0;\n }\n if (fresh || cached === undefined) {\n var inner = document.createElement(\'div\');\n inner.style.width = \'100%\';\n inner.style.height = \'200px\';\n var outer = document.createElement(\'div\');\n var outerStyle = outer.style;\n outerStyle.position = \'absolute\';\n outerStyle.top = \'0\';\n outerStyle.left = \'0\';\n outerStyle.pointerEvents = \'none\';\n outerStyle.visibility = \'hidden\';\n outerStyle.width = \'200px\';\n outerStyle.height = \'150px\';\n outerStyle.overflow = \'hidden\';\n outer.appendChild(inner);\n document.body.appendChild(outer);\n var widthContained = inner.offsetWidth;\n outer.style.overflow = \'scroll\';\n var widthScroll = inner.offsetWidth;\n if (widthContained === widthScroll) {\n widthScroll = outer.clientWidth;\n }\n document.body.removeChild(outer);\n cached = widthContained - widthScroll;\n }\n return cached;\n}\nfunction ensureSize(str) {\n var match = str.match(/^(.*)px$/);\n var value = Number(match === null || match === void 0 ? void 0 : match[1]);\n return Number.isNaN(value) ? getScrollBarSize() : value;\n}\nfunction getTargetScrollBarSize(target) {\n if (typeof document === \'undefined\' || !target || !(target instanceof Element)) {\n return {\n width: 0,\n height: 0\n };\n }\n var _getComputedStyle = getComputedStyle(target, \'::-webkit-scrollbar\'),\n width = _getComputedStyle.width,\n height = _getComputedStyle.height;\n return {\n width: ensureSize(width),\n height: ensureSize(height)\n };\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/util.js\n/**\n * Test usage export. Do not use in your production\n */\nfunction isBodyOverflowing() {\n return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) && window.innerWidth > document.body.offsetWidth;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/useScrollLocker.js\n\n\n\n\n\n\nvar UNIQUE_ID = "rc-util-locker-".concat(Date.now());\nvar uuid = 0;\nfunction useScrollLocker(lock) {\n var mergedLock = !!lock;\n var _React$useState = react.useState(function () {\n uuid += 1;\n return "".concat(UNIQUE_ID, "_").concat(uuid);\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 1),\n id = _React$useState2[0];\n hooks_useLayoutEffect(function () {\n if (mergedLock) {\n var scrollbarSize = getScrollBarSize();\n var isOverflow = isBodyOverflowing();\n updateCSS("\\nhtml body {\\n overflow-y: hidden;\\n ".concat(isOverflow ? "width: calc(100% - ".concat(scrollbarSize, "px);") : \'\', "\\n}"), id);\n } else {\n removeCSS(id);\n }\n return function () {\n removeCSS(id);\n };\n }, [mergedLock, id]);\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/mock.js\nvar inline = false;\nfunction inlineMock(nextInline) {\n if (typeof nextInline === \'boolean\') {\n inline = nextInline;\n }\n return inline;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/Portal.js\n\n\n\n\n\n\n\n\n\n\nvar getPortalContainer = function getPortalContainer(getContainer) {\n if (getContainer === false) {\n return false;\n }\n if (!canUseDom() || !getContainer) {\n return null;\n }\n if (typeof getContainer === \'string\') {\n return document.querySelector(getContainer);\n }\n if (typeof getContainer === \'function\') {\n return getContainer();\n }\n return getContainer;\n};\nvar Portal = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var open = props.open,\n autoLock = props.autoLock,\n getContainer = props.getContainer,\n debug = props.debug,\n _props$autoDestroy = props.autoDestroy,\n autoDestroy = _props$autoDestroy === void 0 ? true : _props$autoDestroy,\n children = props.children;\n var _React$useState = react.useState(open),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n shouldRender = _React$useState2[0],\n setShouldRender = _React$useState2[1];\n var mergedRender = shouldRender || open;\n\n // ========================= Warning =========================\n if (false) {}\n\n // ====================== Should Render ======================\n react.useEffect(function () {\n if (autoDestroy || open) {\n setShouldRender(open);\n }\n }, [open, autoDestroy]);\n\n // ======================== Container ========================\n var _React$useState3 = react.useState(function () {\n return getPortalContainer(getContainer);\n }),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n innerContainer = _React$useState4[0],\n setInnerContainer = _React$useState4[1];\n react.useEffect(function () {\n var customizeContainer = getPortalContainer(getContainer);\n\n // Tell component that we check this in effect which is safe to be `null`\n setInnerContainer(customizeContainer !== null && customizeContainer !== void 0 ? customizeContainer : null);\n });\n var _useDom = useDom(mergedRender && !innerContainer, debug),\n _useDom2 = slicedToArray_slicedToArray(_useDom, 2),\n defaultContainer = _useDom2[0],\n queueCreate = _useDom2[1];\n var mergedContainer = innerContainer !== null && innerContainer !== void 0 ? innerContainer : defaultContainer;\n\n // ========================= Locker ==========================\n useScrollLocker(autoLock && open && canUseDom() && (mergedContainer === defaultContainer || mergedContainer === document.body));\n\n // =========================== Ref ===========================\n var childRef = null;\n if (children && supportRef(children) && ref) {\n var _ref = children;\n childRef = _ref.ref;\n }\n var mergedRef = useComposeRef(childRef, ref);\n\n // ========================= Render ==========================\n // Do not render when nothing need render\n // When innerContainer is `undefined`, it may not ready since user use ref in the same render\n if (!mergedRender || !canUseDom() || innerContainer === undefined) {\n return null;\n }\n\n // Render inline\n var renderInline = mergedContainer === false || inlineMock();\n var reffedChildren = children;\n if (ref) {\n reffedChildren = /*#__PURE__*/react.cloneElement(children, {\n ref: mergedRef\n });\n }\n return /*#__PURE__*/react.createElement(es_Context.Provider, {\n value: queueCreate\n }, renderInline ? reffedChildren : /*#__PURE__*/(0,react_dom.createPortal)(reffedChildren, mergedContainer));\n});\nif (false) {}\n/* harmony default export */ const es_Portal = (Portal);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/portal/es/index.js\n\n\n\n/* harmony default export */ const portal_es = (es_Portal);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Children/toArray.js\n\n\nfunction toArray(children) {\n var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var ret = [];\n react.Children.forEach(children, function (child) {\n if ((child === undefined || child === null) && !option.keepEmpty) {\n return;\n }\n if (Array.isArray(child)) {\n ret = ret.concat(toArray(child));\n } else if ((0,react_is.isFragment)(child) && child.props) {\n ret = ret.concat(toArray(child.props.children, option));\n } else {\n ret.push(child);\n }\n });\n return ret;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/findDOMNode.js\n\n\nfunction isDOM(node) {\n // https://developer.mozilla.org/en-US/docs/Web/API/Element\n // Since XULElement is also subclass of Element, we only need HTMLElement and SVGElement\n return node instanceof HTMLElement || node instanceof SVGElement;\n}\n\n/**\n * Return if a node is a DOM node. Else will return by `findDOMNode`\n */\nfunction findDOMNode(node) {\n if (isDOM(node)) {\n return node;\n }\n if (node instanceof react.Component) {\n return react_dom.findDOMNode(node);\n }\n return null;\n}\n;// CONCATENATED MODULE: ./node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js\n/**\r\n * A collection of shims that provide minimal functionality of the ES6 collections.\r\n *\r\n * These implementations are not meant to be used outside of the ResizeObserver\r\n * modules as they cover only a limited range of use cases.\r\n */\r\n/* eslint-disable require-jsdoc, valid-jsdoc */\r\nvar MapShim = (function () {\r\n if (typeof Map !== \'undefined\') {\r\n return Map;\r\n }\r\n /**\r\n * Returns index in provided array that matches the specified key.\r\n *\r\n * @param {Array<Array>} arr\r\n * @param {*} key\r\n * @returns {number}\r\n */\r\n function getIndex(arr, key) {\r\n var result = -1;\r\n arr.some(function (entry, index) {\r\n if (entry[0] === key) {\r\n result = index;\r\n return true;\r\n }\r\n return false;\r\n });\r\n return result;\r\n }\r\n return /** @class */ (function () {\r\n function class_1() {\r\n this.__entries__ = [];\r\n }\r\n Object.defineProperty(class_1.prototype, "size", {\r\n /**\r\n * @returns {boolean}\r\n */\r\n get: function () {\r\n return this.__entries__.length;\r\n },\r\n enumerable: true,\r\n configurable: true\r\n });\r\n /**\r\n * @param {*} key\r\n * @returns {*}\r\n */\r\n class_1.prototype.get = function (key) {\r\n var index = getIndex(this.__entries__, key);\r\n var entry = this.__entries__[index];\r\n return entry && entry[1];\r\n };\r\n /**\r\n * @param {*} key\r\n * @param {*} value\r\n * @returns {void}\r\n */\r\n class_1.prototype.set = function (key, value) {\r\n var index = getIndex(this.__entries__, key);\r\n if (~index) {\r\n this.__entries__[index][1] = value;\r\n }\r\n else {\r\n this.__entries__.push([key, value]);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.delete = function (key) {\r\n var entries = this.__entries__;\r\n var index = getIndex(entries, key);\r\n if (~index) {\r\n entries.splice(index, 1);\r\n }\r\n };\r\n /**\r\n * @param {*} key\r\n * @returns {void}\r\n */\r\n class_1.prototype.has = function (key) {\r\n return !!~getIndex(this.__entries__, key);\r\n };\r\n /**\r\n * @returns {void}\r\n */\r\n class_1.prototype.clear = function () {\r\n this.__entries__.splice(0);\r\n };\r\n /**\r\n * @param {Function} callback\r\n * @param {*} [ctx=null]\r\n * @returns {void}\r\n */\r\n class_1.prototype.forEach = function (callback, ctx) {\r\n if (ctx === void 0) { ctx = null; }\r\n for (var _i = 0, _a = this.__entries__; _i < _a.length; _i++) {\r\n var entry = _a[_i];\r\n callback.call(ctx, entry[1], entry[0]);\r\n }\r\n };\r\n return class_1;\r\n }());\r\n})();\n\n/**\r\n * Detects whether window and document objects are available in current environment.\r\n */\r\nvar isBrowser = typeof window !== \'undefined\' && typeof document !== \'undefined\' && window.document === document;\n\n// Returns global object of a current environment.\r\nvar global$1 = (function () {\r\n if (typeof __webpack_require__.g !== \'undefined\' && __webpack_require__.g.Math === Math) {\r\n return __webpack_require__.g;\r\n }\r\n if (typeof self !== \'undefined\' && self.Math === Math) {\r\n return self;\r\n }\r\n if (typeof window !== \'undefined\' && window.Math === Math) {\r\n return window;\r\n }\r\n // eslint-disable-next-line no-new-func\r\n return Function(\'return this\')();\r\n})();\n\n/**\r\n * A shim for the requestAnimationFrame which falls back to the setTimeout if\r\n * first one is not supported.\r\n *\r\n * @returns {number} Requests\' identifier.\r\n */\r\nvar requestAnimationFrame$1 = (function () {\r\n if (typeof requestAnimationFrame === \'function\') {\r\n // It\'s required to use a bounded function because IE sometimes throws\r\n // an "Invalid calling object" error if rAF is invoked without the global\r\n // object on the left hand side.\r\n return requestAnimationFrame.bind(global$1);\r\n }\r\n return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };\r\n})();\n\n// Defines minimum timeout before adding a trailing call.\r\nvar trailingTimeout = 2;\r\n/**\r\n * Creates a wrapper function which ensures that provided callback will be\r\n * invoked only once during the specified delay period.\r\n *\r\n * @param {Function} callback - Function to be invoked after the delay period.\r\n * @param {number} delay - Delay after which to invoke callback.\r\n * @returns {Function}\r\n */\r\nfunction throttle (callback, delay) {\r\n var leadingCall = false, trailingCall = false, lastCallTime = 0;\r\n /**\r\n * Invokes the original callback function and schedules new invocation if\r\n * the "proxy" was called during current request.\r\n *\r\n * @returns {void}\r\n */\r\n function resolvePending() {\r\n if (leadingCall) {\r\n leadingCall = false;\r\n callback();\r\n }\r\n if (trailingCall) {\r\n proxy();\r\n }\r\n }\r\n /**\r\n * Callback invoked after the specified delay. It will further postpone\r\n * invocation of the original function delegating it to the\r\n * requestAnimationFrame.\r\n *\r\n * @returns {void}\r\n */\r\n function timeoutCallback() {\r\n requestAnimationFrame$1(resolvePending);\r\n }\r\n /**\r\n * Schedules invocation of the original function.\r\n *\r\n * @returns {void}\r\n */\r\n function proxy() {\r\n var timeStamp = Date.now();\r\n if (leadingCall) {\r\n // Reject immediately following calls.\r\n if (timeStamp - lastCallTime < trailingTimeout) {\r\n return;\r\n }\r\n // Schedule new call to be in invoked when the pending one is resolved.\r\n // This is important for "transitions" which never actually start\r\n // immediately so there is a chance that we might miss one if change\r\n // happens amids the pending invocation.\r\n trailingCall = true;\r\n }\r\n else {\r\n leadingCall = true;\r\n trailingCall = false;\r\n setTimeout(timeoutCallback, delay);\r\n }\r\n lastCallTime = timeStamp;\r\n }\r\n return proxy;\r\n}\n\n// Minimum delay before invoking the update of observers.\r\nvar REFRESH_DELAY = 20;\r\n// A list of substrings of CSS properties used to find transition events that\r\n// might affect dimensions of observed elements.\r\nvar transitionKeys = [\'top\', \'right\', \'bottom\', \'left\', \'width\', \'height\', \'size\', \'weight\'];\r\n// Check if MutationObserver is available.\r\nvar mutationObserverSupported = typeof MutationObserver !== \'undefined\';\r\n/**\r\n * Singleton controller class which handles updates of ResizeObserver instances.\r\n */\r\nvar ResizeObserverController = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserverController.\r\n *\r\n * @private\r\n */\r\n function ResizeObserverController() {\r\n /**\r\n * Indicates whether DOM listeners have been added.\r\n *\r\n * @private {boolean}\r\n */\r\n this.connected_ = false;\r\n /**\r\n * Tells that controller has subscribed for Mutation Events.\r\n *\r\n * @private {boolean}\r\n */\r\n this.mutationEventsAdded_ = false;\r\n /**\r\n * Keeps reference to the instance of MutationObserver.\r\n *\r\n * @private {MutationObserver}\r\n */\r\n this.mutationsObserver_ = null;\r\n /**\r\n * A list of connected observers.\r\n *\r\n * @private {Array<ResizeObserverSPI>}\r\n */\r\n this.observers_ = [];\r\n this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);\r\n this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY);\r\n }\r\n /**\r\n * Adds observer to observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be added.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.addObserver = function (observer) {\r\n if (!~this.observers_.indexOf(observer)) {\r\n this.observers_.push(observer);\r\n }\r\n // Add listeners if they haven\'t been added yet.\r\n if (!this.connected_) {\r\n this.connect_();\r\n }\r\n };\r\n /**\r\n * Removes observer from observers list.\r\n *\r\n * @param {ResizeObserverSPI} observer - Observer to be removed.\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.removeObserver = function (observer) {\r\n var observers = this.observers_;\r\n var index = observers.indexOf(observer);\r\n // Remove observer if it\'s present in registry.\r\n if (~index) {\r\n observers.splice(index, 1);\r\n }\r\n // Remove listeners if controller has no connected observers.\r\n if (!observers.length && this.connected_) {\r\n this.disconnect_();\r\n }\r\n };\r\n /**\r\n * Invokes the update of observers. It will continue running updates insofar\r\n * it detects changes.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.refresh = function () {\r\n var changesDetected = this.updateObservers_();\r\n // Continue running updates if changes have been detected as there might\r\n // be future ones caused by CSS transitions.\r\n if (changesDetected) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Updates every observer from observers list and notifies them of queued\r\n * entries.\r\n *\r\n * @private\r\n * @returns {boolean} Returns "true" if any observer has detected changes in\r\n * dimensions of it\'s elements.\r\n */\r\n ResizeObserverController.prototype.updateObservers_ = function () {\r\n // Collect observers that have active observations.\r\n var activeObservers = this.observers_.filter(function (observer) {\r\n return observer.gatherActive(), observer.hasActive();\r\n });\r\n // Deliver notifications in a separate cycle in order to avoid any\r\n // collisions between observers, e.g. when multiple instances of\r\n // ResizeObserver are tracking the same element and the callback of one\r\n // of them changes content dimensions of the observed target. Sometimes\r\n // this may result in notifications being blocked for the rest of observers.\r\n activeObservers.forEach(function (observer) { return observer.broadcastActive(); });\r\n return activeObservers.length > 0;\r\n };\r\n /**\r\n * Initializes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.connect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already added.\r\n if (!isBrowser || this.connected_) {\r\n return;\r\n }\r\n // Subscription to the "Transitionend" event is used as a workaround for\r\n // delayed transitions. This way it\'s possible to capture at least the\r\n // final state of an element.\r\n document.addEventListener(\'transitionend\', this.onTransitionEnd_);\r\n window.addEventListener(\'resize\', this.refresh);\r\n if (mutationObserverSupported) {\r\n this.mutationsObserver_ = new MutationObserver(this.refresh);\r\n this.mutationsObserver_.observe(document, {\r\n attributes: true,\r\n childList: true,\r\n characterData: true,\r\n subtree: true\r\n });\r\n }\r\n else {\r\n document.addEventListener(\'DOMSubtreeModified\', this.refresh);\r\n this.mutationEventsAdded_ = true;\r\n }\r\n this.connected_ = true;\r\n };\r\n /**\r\n * Removes DOM listeners.\r\n *\r\n * @private\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.disconnect_ = function () {\r\n // Do nothing if running in a non-browser environment or if listeners\r\n // have been already removed.\r\n if (!isBrowser || !this.connected_) {\r\n return;\r\n }\r\n document.removeEventListener(\'transitionend\', this.onTransitionEnd_);\r\n window.removeEventListener(\'resize\', this.refresh);\r\n if (this.mutationsObserver_) {\r\n this.mutationsObserver_.disconnect();\r\n }\r\n if (this.mutationEventsAdded_) {\r\n document.removeEventListener(\'DOMSubtreeModified\', this.refresh);\r\n }\r\n this.mutationsObserver_ = null;\r\n this.mutationEventsAdded_ = false;\r\n this.connected_ = false;\r\n };\r\n /**\r\n * "Transitionend" event handler.\r\n *\r\n * @private\r\n * @param {TransitionEvent} event\r\n * @returns {void}\r\n */\r\n ResizeObserverController.prototype.onTransitionEnd_ = function (_a) {\r\n var _b = _a.propertyName, propertyName = _b === void 0 ? \'\' : _b;\r\n // Detect whether transition may affect dimensions of an element.\r\n var isReflowProperty = transitionKeys.some(function (key) {\r\n return !!~propertyName.indexOf(key);\r\n });\r\n if (isReflowProperty) {\r\n this.refresh();\r\n }\r\n };\r\n /**\r\n * Returns instance of the ResizeObserverController.\r\n *\r\n * @returns {ResizeObserverController}\r\n */\r\n ResizeObserverController.getInstance = function () {\r\n if (!this.instance_) {\r\n this.instance_ = new ResizeObserverController();\r\n }\r\n return this.instance_;\r\n };\r\n /**\r\n * Holds reference to the controller\'s instance.\r\n *\r\n * @private {ResizeObserverController}\r\n */\r\n ResizeObserverController.instance_ = null;\r\n return ResizeObserverController;\r\n}());\n\n/**\r\n * Defines non-writable/enumerable properties of the provided target object.\r\n *\r\n * @param {Object} target - Object for which to define properties.\r\n * @param {Object} props - Properties to be defined.\r\n * @returns {Object} Target object.\r\n */\r\nvar defineConfigurable = (function (target, props) {\r\n for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) {\r\n var key = _a[_i];\r\n Object.defineProperty(target, key, {\r\n value: props[key],\r\n enumerable: false,\r\n writable: false,\r\n configurable: true\r\n });\r\n }\r\n return target;\r\n});\n\n/**\r\n * Returns the global object associated with provided element.\r\n *\r\n * @param {Object} target\r\n * @returns {Object}\r\n */\r\nvar getWindowOf = (function (target) {\r\n // Assume that the element is an instance of Node, which means that it\r\n // has the "ownerDocument" property from which we can retrieve a\r\n // corresponding global object.\r\n var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;\r\n // Return the local global object if it\'s not possible extract one from\r\n // provided element.\r\n return ownerGlobal || global$1;\r\n});\n\n// Placeholder of an empty content rectangle.\r\nvar emptyRect = createRectInit(0, 0, 0, 0);\r\n/**\r\n * Converts provided string to a number.\r\n *\r\n * @param {number|string} value\r\n * @returns {number}\r\n */\r\nfunction toFloat(value) {\r\n return parseFloat(value) || 0;\r\n}\r\n/**\r\n * Extracts borders size from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @param {...string} positions - Borders positions (top, right, ...)\r\n * @returns {number}\r\n */\r\nfunction getBordersSize(styles) {\r\n var positions = [];\r\n for (var _i = 1; _i < arguments.length; _i++) {\r\n positions[_i - 1] = arguments[_i];\r\n }\r\n return positions.reduce(function (size, position) {\r\n var value = styles[\'border-\' + position + \'-width\'];\r\n return size + toFloat(value);\r\n }, 0);\r\n}\r\n/**\r\n * Extracts paddings sizes from provided styles.\r\n *\r\n * @param {CSSStyleDeclaration} styles\r\n * @returns {Object} Paddings box.\r\n */\r\nfunction getPaddings(styles) {\r\n var positions = [\'top\', \'right\', \'bottom\', \'left\'];\r\n var paddings = {};\r\n for (var _i = 0, positions_1 = positions; _i < positions_1.length; _i++) {\r\n var position = positions_1[_i];\r\n var value = styles[\'padding-\' + position];\r\n paddings[position] = toFloat(value);\r\n }\r\n return paddings;\r\n}\r\n/**\r\n * Calculates content rectangle of provided SVG element.\r\n *\r\n * @param {SVGGraphicsElement} target - Element content rectangle of which needs\r\n * to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getSVGContentRect(target) {\r\n var bbox = target.getBBox();\r\n return createRectInit(0, 0, bbox.width, bbox.height);\r\n}\r\n/**\r\n * Calculates content rectangle of provided HTMLElement.\r\n *\r\n * @param {HTMLElement} target - Element for which to calculate the content rectangle.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getHTMLElementContentRect(target) {\r\n // Client width & height properties can\'t be\r\n // used exclusively as they provide rounded values.\r\n var clientWidth = target.clientWidth, clientHeight = target.clientHeight;\r\n // By this condition we can catch all non-replaced inline, hidden and\r\n // detached elements. Though elements with width & height properties less\r\n // than 0.5 will be discarded as well.\r\n //\r\n // Without it we would need to implement separate methods for each of\r\n // those cases and it\'s not possible to perform a precise and performance\r\n // effective test for hidden elements. E.g. even jQuery\'s \':visible\' filter\r\n // gives wrong results for elements with width & height less than 0.5.\r\n if (!clientWidth && !clientHeight) {\r\n return emptyRect;\r\n }\r\n var styles = getWindowOf(target).getComputedStyle(target);\r\n var paddings = getPaddings(styles);\r\n var horizPad = paddings.left + paddings.right;\r\n var vertPad = paddings.top + paddings.bottom;\r\n // Computed styles of width & height are being used because they are the\r\n // only dimensions available to JS that contain non-rounded values. It could\r\n // be possible to utilize the getBoundingClientRect if only it\'s data wasn\'t\r\n // affected by CSS transformations let alone paddings, borders and scroll bars.\r\n var width = toFloat(styles.width), height = toFloat(styles.height);\r\n // Width & height include paddings and borders when the \'border-box\' box\r\n // model is applied (except for IE).\r\n if (styles.boxSizing === \'border-box\') {\r\n // Following conditions are required to handle Internet Explorer which\r\n // doesn\'t include paddings and borders to computed CSS dimensions.\r\n //\r\n // We can say that if CSS dimensions + paddings are equal to the "client"\r\n // properties then it\'s either IE, and thus we don\'t need to subtract\r\n // anything, or an element merely doesn\'t have paddings/borders styles.\r\n if (Math.round(width + horizPad) !== clientWidth) {\r\n width -= getBordersSize(styles, \'left\', \'right\') + horizPad;\r\n }\r\n if (Math.round(height + vertPad) !== clientHeight) {\r\n height -= getBordersSize(styles, \'top\', \'bottom\') + vertPad;\r\n }\r\n }\r\n // Following steps can\'t be applied to the document\'s root element as its\r\n // client[Width/Height] properties represent viewport area of the window.\r\n // Besides, it\'s as well not necessary as the <html> itself neither has\r\n // rendered scroll bars nor it can be clipped.\r\n if (!isDocumentElement(target)) {\r\n // In some browsers (only in Firefox, actually) CSS width & height\r\n // include scroll bars size which can be removed at this step as scroll\r\n // bars are the only difference between rounded dimensions + paddings\r\n // and "client" properties, though that is not always true in Chrome.\r\n var vertScrollbar = Math.round(width + horizPad) - clientWidth;\r\n var horizScrollbar = Math.round(height + vertPad) - clientHeight;\r\n // Chrome has a rather weird rounding of "client" properties.\r\n // E.g. for an element with content width of 314.2px it sometimes gives\r\n // the client width of 315px and for the width of 314.7px it may give\r\n // 314px. And it doesn\'t happen all the time. So just ignore this delta\r\n // as a non-relevant.\r\n if (Math.abs(vertScrollbar) !== 1) {\r\n width -= vertScrollbar;\r\n }\r\n if (Math.abs(horizScrollbar) !== 1) {\r\n height -= horizScrollbar;\r\n }\r\n }\r\n return createRectInit(paddings.left, paddings.top, width, height);\r\n}\r\n/**\r\n * Checks whether provided element is an instance of the SVGGraphicsElement.\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nvar isSVGGraphicsElement = (function () {\r\n // Some browsers, namely IE and Edge, don\'t have the SVGGraphicsElement\r\n // interface.\r\n if (typeof SVGGraphicsElement !== \'undefined\') {\r\n return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };\r\n }\r\n // If it\'s so, then check that element is at least an instance of the\r\n // SVGElement and that it has the "getBBox" method.\r\n // eslint-disable-next-line no-extra-parens\r\n return function (target) { return (target instanceof getWindowOf(target).SVGElement &&\r\n typeof target.getBBox === \'function\'); };\r\n})();\r\n/**\r\n * Checks whether provided element is a document element (<html>).\r\n *\r\n * @param {Element} target - Element to be checked.\r\n * @returns {boolean}\r\n */\r\nfunction isDocumentElement(target) {\r\n return target === getWindowOf(target).document.documentElement;\r\n}\r\n/**\r\n * Calculates an appropriate content rectangle for provided html or svg element.\r\n *\r\n * @param {Element} target - Element content rectangle of which needs to be calculated.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction getContentRect(target) {\r\n if (!isBrowser) {\r\n return emptyRect;\r\n }\r\n if (isSVGGraphicsElement(target)) {\r\n return getSVGContentRect(target);\r\n }\r\n return getHTMLElementContentRect(target);\r\n}\r\n/**\r\n * Creates rectangle with an interface of the DOMRectReadOnly.\r\n * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly\r\n *\r\n * @param {DOMRectInit} rectInit - Object with rectangle\'s x/y coordinates and dimensions.\r\n * @returns {DOMRectReadOnly}\r\n */\r\nfunction createReadOnlyRect(_a) {\r\n var x = _a.x, y = _a.y, width = _a.width, height = _a.height;\r\n // If DOMRectReadOnly is available use it as a prototype for the rectangle.\r\n var Constr = typeof DOMRectReadOnly !== \'undefined\' ? DOMRectReadOnly : Object;\r\n var rect = Object.create(Constr.prototype);\r\n // Rectangle\'s properties are not writable and non-enumerable.\r\n defineConfigurable(rect, {\r\n x: x, y: y, width: width, height: height,\r\n top: y,\r\n right: x + width,\r\n bottom: height + y,\r\n left: x\r\n });\r\n return rect;\r\n}\r\n/**\r\n * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.\r\n * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit\r\n *\r\n * @param {number} x - X coordinate.\r\n * @param {number} y - Y coordinate.\r\n * @param {number} width - Rectangle\'s width.\r\n * @param {number} height - Rectangle\'s height.\r\n * @returns {DOMRectInit}\r\n */\r\nfunction createRectInit(x, y, width, height) {\r\n return { x: x, y: y, width: width, height: height };\r\n}\n\n/**\r\n * Class that is responsible for computations of the content rectangle of\r\n * provided DOM element and for keeping track of it\'s changes.\r\n */\r\nvar ResizeObservation = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObservation.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n */\r\n function ResizeObservation(target) {\r\n /**\r\n * Broadcasted width of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastWidth = 0;\r\n /**\r\n * Broadcasted height of content rectangle.\r\n *\r\n * @type {number}\r\n */\r\n this.broadcastHeight = 0;\r\n /**\r\n * Reference to the last observed content rectangle.\r\n *\r\n * @private {DOMRectInit}\r\n */\r\n this.contentRect_ = createRectInit(0, 0, 0, 0);\r\n this.target = target;\r\n }\r\n /**\r\n * Updates content rectangle and tells whether it\'s width or height properties\r\n * have changed since the last broadcast.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObservation.prototype.isActive = function () {\r\n var rect = getContentRect(this.target);\r\n this.contentRect_ = rect;\r\n return (rect.width !== this.broadcastWidth ||\r\n rect.height !== this.broadcastHeight);\r\n };\r\n /**\r\n * Updates \'broadcastWidth\' and \'broadcastHeight\' properties with a data\r\n * from the corresponding properties of the last observed content rectangle.\r\n *\r\n * @returns {DOMRectInit} Last observed content rectangle.\r\n */\r\n ResizeObservation.prototype.broadcastRect = function () {\r\n var rect = this.contentRect_;\r\n this.broadcastWidth = rect.width;\r\n this.broadcastHeight = rect.height;\r\n return rect;\r\n };\r\n return ResizeObservation;\r\n}());\n\nvar ResizeObserverEntry = /** @class */ (function () {\r\n /**\r\n * Creates an instance of ResizeObserverEntry.\r\n *\r\n * @param {Element} target - Element that is being observed.\r\n * @param {DOMRectInit} rectInit - Data of the element\'s content rectangle.\r\n */\r\n function ResizeObserverEntry(target, rectInit) {\r\n var contentRect = createReadOnlyRect(rectInit);\r\n // According to the specification following properties are not writable\r\n // and are also not enumerable in the native implementation.\r\n //\r\n // Property accessors are not being used as they\'d require to define a\r\n // private WeakMap storage which may cause memory leaks in browsers that\r\n // don\'t support this type of collections.\r\n defineConfigurable(this, { target: target, contentRect: contentRect });\r\n }\r\n return ResizeObserverEntry;\r\n}());\n\nvar ResizeObserverSPI = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback function that is invoked\r\n * when one of the observed elements changes it\'s content dimensions.\r\n * @param {ResizeObserverController} controller - Controller instance which\r\n * is responsible for the updates of observer.\r\n * @param {ResizeObserver} callbackCtx - Reference to the public\r\n * ResizeObserver instance which will be passed to callback function.\r\n */\r\n function ResizeObserverSPI(callback, controller, callbackCtx) {\r\n /**\r\n * Collection of resize observations that have detected changes in dimensions\r\n * of elements.\r\n *\r\n * @private {Array<ResizeObservation>}\r\n */\r\n this.activeObservations_ = [];\r\n /**\r\n * Registry of the ResizeObservation instances.\r\n *\r\n * @private {Map<Element, ResizeObservation>}\r\n */\r\n this.observations_ = new MapShim();\r\n if (typeof callback !== \'function\') {\r\n throw new TypeError(\'The callback provided as parameter 1 is not a function.\');\r\n }\r\n this.callback_ = callback;\r\n this.controller_ = controller;\r\n this.callbackCtx_ = callbackCtx;\r\n }\r\n /**\r\n * Starts observing provided element.\r\n *\r\n * @param {Element} target - Element to be observed.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.observe = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n // Do nothing if current environment doesn\'t have the Element interface.\r\n if (typeof Element === \'undefined\' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError(\'parameter 1 is not of type "Element".\');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is already being observed.\r\n if (observations.has(target)) {\r\n return;\r\n }\r\n observations.set(target, new ResizeObservation(target));\r\n this.controller_.addObserver(this);\r\n // Force the update of observations.\r\n this.controller_.refresh();\r\n };\r\n /**\r\n * Stops observing provided element.\r\n *\r\n * @param {Element} target - Element to stop observing.\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.unobserve = function (target) {\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n // Do nothing if current environment doesn\'t have the Element interface.\r\n if (typeof Element === \'undefined\' || !(Element instanceof Object)) {\r\n return;\r\n }\r\n if (!(target instanceof getWindowOf(target).Element)) {\r\n throw new TypeError(\'parameter 1 is not of type "Element".\');\r\n }\r\n var observations = this.observations_;\r\n // Do nothing if element is not being observed.\r\n if (!observations.has(target)) {\r\n return;\r\n }\r\n observations.delete(target);\r\n if (!observations.size) {\r\n this.controller_.removeObserver(this);\r\n }\r\n };\r\n /**\r\n * Stops observing all elements.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.disconnect = function () {\r\n this.clearActive();\r\n this.observations_.clear();\r\n this.controller_.removeObserver(this);\r\n };\r\n /**\r\n * Collects observation instances the associated element of which has changed\r\n * it\'s content rectangle.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.gatherActive = function () {\r\n var _this = this;\r\n this.clearActive();\r\n this.observations_.forEach(function (observation) {\r\n if (observation.isActive()) {\r\n _this.activeObservations_.push(observation);\r\n }\r\n });\r\n };\r\n /**\r\n * Invokes initial callback function with a list of ResizeObserverEntry\r\n * instances collected from active resize observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.broadcastActive = function () {\r\n // Do nothing if observer doesn\'t have active observations.\r\n if (!this.hasActive()) {\r\n return;\r\n }\r\n var ctx = this.callbackCtx_;\r\n // Create ResizeObserverEntry instance for every active observation.\r\n var entries = this.activeObservations_.map(function (observation) {\r\n return new ResizeObserverEntry(observation.target, observation.broadcastRect());\r\n });\r\n this.callback_.call(ctx, entries, ctx);\r\n this.clearActive();\r\n };\r\n /**\r\n * Clears the collection of active observations.\r\n *\r\n * @returns {void}\r\n */\r\n ResizeObserverSPI.prototype.clearActive = function () {\r\n this.activeObservations_.splice(0);\r\n };\r\n /**\r\n * Tells whether observer has active observations.\r\n *\r\n * @returns {boolean}\r\n */\r\n ResizeObserverSPI.prototype.hasActive = function () {\r\n return this.activeObservations_.length > 0;\r\n };\r\n return ResizeObserverSPI;\r\n}());\n\n// Registry of internal observers. If WeakMap is not available use current shim\r\n// for the Map collection as it has all required methods and because WeakMap\r\n// can\'t be fully polyfilled anyway.\r\nvar observers = typeof WeakMap !== \'undefined\' ? new WeakMap() : new MapShim();\r\n/**\r\n * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation\r\n * exposing only those methods and properties that are defined in the spec.\r\n */\r\nvar ResizeObserver = /** @class */ (function () {\r\n /**\r\n * Creates a new instance of ResizeObserver.\r\n *\r\n * @param {ResizeObserverCallback} callback - Callback that is invoked when\r\n * dimensions of the observed elements change.\r\n */\r\n function ResizeObserver(callback) {\r\n if (!(this instanceof ResizeObserver)) {\r\n throw new TypeError(\'Cannot call a class as a function.\');\r\n }\r\n if (!arguments.length) {\r\n throw new TypeError(\'1 argument required, but only 0 present.\');\r\n }\r\n var controller = ResizeObserverController.getInstance();\r\n var observer = new ResizeObserverSPI(callback, controller, this);\r\n observers.set(this, observer);\r\n }\r\n return ResizeObserver;\r\n}());\r\n// Expose public methods of ResizeObserver.\r\n[\r\n \'observe\',\r\n \'unobserve\',\r\n \'disconnect\'\r\n].forEach(function (method) {\r\n ResizeObserver.prototype[method] = function () {\r\n var _a;\r\n return (_a = observers.get(this))[method].apply(_a, arguments);\r\n };\r\n});\n\nvar index = (function () {\r\n // Export existing implementation if available.\r\n if (typeof global$1.ResizeObserver !== \'undefined\') {\r\n return global$1.ResizeObserver;\r\n }\r\n return ResizeObserver;\r\n})();\n\n/* harmony default export */ const ResizeObserver_es = (index);\n\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/utils/observerUtil.js\n\n// =============================== Const ===============================\nvar elementListeners = new Map();\nfunction onResize(entities) {\n entities.forEach(function (entity) {\n var _elementListeners$get;\n var target = entity.target;\n (_elementListeners$get = elementListeners.get(target)) === null || _elementListeners$get === void 0 ? void 0 : _elementListeners$get.forEach(function (listener) {\n return listener(target);\n });\n });\n}\n// Note: ResizeObserver polyfill not support option to measure border-box resize\nvar resizeObserver = new ResizeObserver_es(onResize);\n// Dev env only\nvar _el = (/* unused pure expression or super */ null && ( false ? 0 : null)); // eslint-disable-line\nvar _rs = (/* unused pure expression or super */ null && ( false ? 0 : null)); // eslint-disable-line\n// ============================== Observe ==============================\nfunction observe(element, callback) {\n if (!elementListeners.has(element)) {\n elementListeners.set(element, new Set());\n resizeObserver.observe(element);\n }\n elementListeners.get(element).add(callback);\n}\nfunction unobserve(element, callback) {\n if (elementListeners.has(element)) {\n elementListeners.get(element).delete(callback);\n if (!elementListeners.get(element).size) {\n resizeObserver.unobserve(element);\n elementListeners.delete(element);\n }\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js\nfunction classCallCheck_classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js\n\nfunction createClass_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_toPropertyKey(descriptor.key), descriptor);\n }\n}\nfunction createClass_createClass(Constructor, protoProps, staticProps) {\n if (protoProps) createClass_defineProperties(Constructor.prototype, protoProps);\n if (staticProps) createClass_defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js\nfunction _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/inherits.js\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== "function" && superClass !== null) {\n throw new TypeError("Super expression must either be null or a function");\n }\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, "prototype", {\n writable: false\n });\n if (superClass) _setPrototypeOf(subClass, superClass);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js\nfunction _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js\nfunction _isNativeReflectConstruct() {\n if (typeof Reflect === "undefined" || !Reflect.construct) return false;\n if (Reflect.construct.sham) return false;\n if (typeof Proxy === "function") return true;\n try {\n Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));\n return true;\n } catch (e) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js\nfunction _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called");\n }\n return self;\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js\n\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (typeof_typeof(call) === "object" || typeof call === "function")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError("Derived constructors may only return object or undefined");\n }\n return _assertThisInitialized(self);\n}\n;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/createSuper.js\n\n\n\nfunction _createSuper(Derived) {\n var hasNativeReflectConstruct = _isNativeReflectConstruct();\n return function _createSuperInternal() {\n var Super = _getPrototypeOf(Derived),\n result;\n if (hasNativeReflectConstruct) {\n var NewTarget = _getPrototypeOf(this).constructor;\n result = Reflect.construct(Super, arguments, NewTarget);\n } else {\n result = Super.apply(this, arguments);\n }\n return _possibleConstructorReturn(this, result);\n };\n}\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/SingleObserver/DomWrapper.js\n\n\n\n\n\n/**\n * Fallback to findDOMNode if origin ref do not provide any dom element\n */\nvar DomWrapper = /*#__PURE__*/function (_React$Component) {\n _inherits(DomWrapper, _React$Component);\n var _super = _createSuper(DomWrapper);\n function DomWrapper() {\n classCallCheck_classCallCheck(this, DomWrapper);\n return _super.apply(this, arguments);\n }\n createClass_createClass(DomWrapper, [{\n key: "render",\n value: function render() {\n return this.props.children;\n }\n }]);\n return DomWrapper;\n}(react.Component);\n\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/Collection.js\n\nvar CollectionContext = /*#__PURE__*/react.createContext(null);\n/**\n * Collect all the resize event from children ResizeObserver\n */\nfunction Collection(_ref) {\n var children = _ref.children,\n onBatchResize = _ref.onBatchResize;\n var resizeIdRef = react.useRef(0);\n var resizeInfosRef = react.useRef([]);\n var onCollectionResize = react.useContext(CollectionContext);\n var onResize = react.useCallback(function (size, element, data) {\n resizeIdRef.current += 1;\n var currentId = resizeIdRef.current;\n resizeInfosRef.current.push({\n size: size,\n element: element,\n data: data\n });\n Promise.resolve().then(function () {\n if (currentId === resizeIdRef.current) {\n onBatchResize === null || onBatchResize === void 0 ? void 0 : onBatchResize(resizeInfosRef.current);\n resizeInfosRef.current = [];\n }\n });\n // Continue bubbling if parent exist\n onCollectionResize === null || onCollectionResize === void 0 ? void 0 : onCollectionResize(size, element, data);\n }, [onBatchResize, onCollectionResize]);\n return /*#__PURE__*/react.createElement(CollectionContext.Provider, {\n value: onResize\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/SingleObserver/index.js\n\n\n\n\n\n\n\nfunction SingleObserver(props, ref) {\n var children = props.children,\n disabled = props.disabled;\n var elementRef = react.useRef(null);\n var wrapperRef = react.useRef(null);\n var onCollectionResize = react.useContext(CollectionContext);\n // =========================== Children ===========================\n var isRenderProps = typeof children === \'function\';\n var mergedChildren = isRenderProps ? children(elementRef) : children;\n // ============================= Size =============================\n var sizeRef = react.useRef({\n width: -1,\n height: -1,\n offsetWidth: -1,\n offsetHeight: -1\n });\n // ============================= Ref ==============================\n var canRef = !isRenderProps && /*#__PURE__*/react.isValidElement(mergedChildren) && supportRef(mergedChildren);\n var originRef = canRef ? mergedChildren.ref : null;\n var mergedRef = react.useMemo(function () {\n return composeRef(originRef, elementRef);\n }, [originRef, elementRef]);\n var getDom = function getDom() {\n return findDOMNode(elementRef.current) || findDOMNode(wrapperRef.current);\n };\n react.useImperativeHandle(ref, function () {\n return getDom();\n });\n // =========================== Observe ============================\n var propsRef = react.useRef(props);\n propsRef.current = props;\n // Handler\n var onInternalResize = react.useCallback(function (target) {\n var _propsRef$current = propsRef.current,\n onResize = _propsRef$current.onResize,\n data = _propsRef$current.data;\n var _target$getBoundingCl = target.getBoundingClientRect(),\n width = _target$getBoundingCl.width,\n height = _target$getBoundingCl.height;\n var offsetWidth = target.offsetWidth,\n offsetHeight = target.offsetHeight;\n /**\n * Resize observer trigger when content size changed.\n * In most case we just care about element size,\n * let\'s use `boundary` instead of `contentRect` here to avoid shaking.\n */\n var fixedWidth = Math.floor(width);\n var fixedHeight = Math.floor(height);\n if (sizeRef.current.width !== fixedWidth || sizeRef.current.height !== fixedHeight || sizeRef.current.offsetWidth !== offsetWidth || sizeRef.current.offsetHeight !== offsetHeight) {\n var size = {\n width: fixedWidth,\n height: fixedHeight,\n offsetWidth: offsetWidth,\n offsetHeight: offsetHeight\n };\n sizeRef.current = size;\n // IE is strange, right?\n var mergedOffsetWidth = offsetWidth === Math.round(width) ? width : offsetWidth;\n var mergedOffsetHeight = offsetHeight === Math.round(height) ? height : offsetHeight;\n var sizeInfo = _objectSpread2(_objectSpread2({}, size), {}, {\n offsetWidth: mergedOffsetWidth,\n offsetHeight: mergedOffsetHeight\n });\n // Let collection know what happened\n onCollectionResize === null || onCollectionResize === void 0 ? void 0 : onCollectionResize(sizeInfo, target, data);\n if (onResize) {\n // defer the callback but not defer to next frame\n Promise.resolve().then(function () {\n onResize(sizeInfo, target);\n });\n }\n }\n }, []);\n // Dynamic observe\n react.useEffect(function () {\n var currentElement = getDom();\n if (currentElement && !disabled) {\n observe(currentElement, onInternalResize);\n }\n return function () {\n return unobserve(currentElement, onInternalResize);\n };\n }, [elementRef.current, disabled]);\n // ============================ Render ============================\n return /*#__PURE__*/react.createElement(DomWrapper, {\n ref: wrapperRef\n }, canRef ? /*#__PURE__*/react.cloneElement(mergedChildren, {\n ref: mergedRef\n }) : mergedChildren);\n}\nvar RefSingleObserver = /*#__PURE__*/react.forwardRef(SingleObserver);\nif (false) {}\n/* harmony default export */ const es_SingleObserver = (RefSingleObserver);\n;// CONCATENATED MODULE: ./node_modules/rc-resize-observer/es/index.js\n\n\n\n\n\n\nvar INTERNAL_PREFIX_KEY = \'rc-observer-key\';\n\n\nfunction es_ResizeObserver(props, ref) {\n var children = props.children;\n var childNodes = typeof children === \'function\' ? [children] : toArray(children);\n if (false) {}\n return childNodes.map(function (child, index) {\n var key = (child === null || child === void 0 ? void 0 : child.key) || "".concat(INTERNAL_PREFIX_KEY, "-").concat(index);\n return /*#__PURE__*/react.createElement(es_SingleObserver, extends_extends({}, props, {\n key: key,\n ref: index === 0 ? ref : undefined\n }), child);\n });\n}\nvar RefResizeObserver = /*#__PURE__*/react.forwardRef(es_ResizeObserver);\nif (false) {}\nRefResizeObserver.Collection = Collection;\n/* harmony default export */ const rc_resize_observer_es = (RefResizeObserver);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/hooks/useId.js\n\n\n\nfunction getUseId() {\n // We need fully clone React function here to avoid webpack warning React 17 do not export `useId`\n var fullClone = _objectSpread2({}, react_namespaceObject);\n return fullClone.useId;\n}\nvar useId_uuid = 0;\n\n/** @private Note only worked in develop env. Not work in production. */\nfunction resetUuid() {\n if (false) {}\n}\nfunction useId(id) {\n // Inner id for accessibility usage. Only work in client side\n var _React$useState = react.useState(\'ssr-id\'),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n innerId = _React$useState2[0],\n setInnerId = _React$useState2[1];\n var useOriginId = getUseId();\n var reactNativeId = useOriginId === null || useOriginId === void 0 ? void 0 : useOriginId();\n react.useEffect(function () {\n if (!useOriginId) {\n var nextId = useId_uuid;\n useId_uuid += 1;\n setInnerId("rc_unique_".concat(nextId));\n }\n }, []);\n\n // Developer passed id is single source of truth\n if (id) {\n return id;\n }\n\n // Test env always return mock id\n if (false) {}\n\n // Return react native id or inner id\n return reactNativeId || innerId;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/isMobile.js\n/* harmony default export */ const es_isMobile = (function () {\n if (typeof navigator === \'undefined\' || typeof window === \'undefined\') {\n return false;\n }\n var agent = navigator.userAgent || navigator.vendor || window.opera;\n return /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(agent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55\\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|\\/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\\/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(agent === null || agent === void 0 ? void 0 : agent.substr(0, 4));\n});\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/context.js\n\nvar TriggerContext = /*#__PURE__*/react.createContext(null);\n/* harmony default export */ const trigger_es_context = (TriggerContext);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useAction.js\n\nfunction useAction_toArray(val) {\n return val ? Array.isArray(val) ? val : [val] : [];\n}\nfunction useAction(mobile, action, showAction, hideAction) {\n return react.useMemo(function () {\n var mergedShowAction = useAction_toArray(showAction !== null && showAction !== void 0 ? showAction : action);\n var mergedHideAction = useAction_toArray(hideAction !== null && hideAction !== void 0 ? hideAction : action);\n var showActionSet = new Set(mergedShowAction);\n var hideActionSet = new Set(mergedHideAction);\n if (mobile) {\n if (showActionSet.has(\'hover\')) {\n showActionSet.delete(\'hover\');\n showActionSet.add(\'click\');\n }\n if (hideActionSet.has(\'hover\')) {\n hideActionSet.delete(\'hover\');\n hideActionSet.add(\'click\');\n }\n }\n return [showActionSet, hideActionSet];\n }, [mobile, action, showAction, hideAction]);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/Dom/isVisible.js\n/* harmony default export */ const isVisible = (function (element) {\n if (!element) {\n return false;\n }\n if (element instanceof Element) {\n if (element.offsetParent) {\n return true;\n }\n if (element.getBBox) {\n var _getBBox = element.getBBox(),\n width = _getBBox.width,\n height = _getBBox.height;\n if (width || height) {\n return true;\n }\n }\n if (element.getBoundingClientRect) {\n var _element$getBoundingC = element.getBoundingClientRect(),\n _width = _element$getBoundingC.width,\n _height = _element$getBoundingC.height;\n if (_width || _height) {\n return true;\n }\n }\n }\n return false;\n});\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/util.js\n\nfunction isPointsEq() {\n var a1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var a2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n var isAlignPoint = arguments.length > 2 ? arguments[2] : undefined;\n if (isAlignPoint) {\n return a1[0] === a2[0];\n }\n return a1[0] === a2[0] && a1[1] === a2[1];\n}\nfunction getAlignPopupClassName(builtinPlacements, prefixCls, align, isAlignPoint) {\n var points = align.points;\n var placements = Object.keys(builtinPlacements);\n for (var i = 0; i < placements.length; i += 1) {\n var _builtinPlacements$pl;\n var placement = placements[i];\n if (isPointsEq((_builtinPlacements$pl = builtinPlacements[placement]) === null || _builtinPlacements$pl === void 0 ? void 0 : _builtinPlacements$pl.points, points, isAlignPoint)) {\n return "".concat(prefixCls, "-placement-").concat(placement);\n }\n }\n return \'\';\n}\n\n/** @deprecated We should not use this if we can refactor all deps */\nfunction getMotion(prefixCls, motion, animation, transitionName) {\n if (motion) {\n return motion;\n }\n if (animation) {\n return {\n motionName: "".concat(prefixCls, "-").concat(animation)\n };\n }\n if (transitionName) {\n return {\n motionName: transitionName\n };\n }\n return null;\n}\nfunction getWin(ele) {\n return ele.ownerDocument.defaultView;\n}\n\n/**\n * Get all the scrollable parent elements of the element\n * @param ele The element to be detected\n * @param areaOnly Only return the parent which will cut visible area\n */\nfunction collectScroller(ele) {\n var scrollerList = [];\n var current = ele === null || ele === void 0 ? void 0 : ele.parentElement;\n var scrollStyle = [\'hidden\', \'scroll\', \'clip\', \'auto\'];\n while (current) {\n var _getWin$getComputedSt = getWin(current).getComputedStyle(current),\n overflowX = _getWin$getComputedSt.overflowX,\n overflowY = _getWin$getComputedSt.overflowY,\n overflow = _getWin$getComputedSt.overflow;\n if ([overflowX, overflowY, overflow].some(function (o) {\n return scrollStyle.includes(o);\n })) {\n scrollerList.push(current);\n }\n current = current.parentElement;\n }\n return scrollerList;\n}\nfunction toNum(num) {\n var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n return Number.isNaN(num) ? defaultValue : num;\n}\nfunction getPxValue(val) {\n return toNum(parseFloat(val), 0);\n}\n/**\n *\n *\n * **************************************\n * * Border *\n * * ************************** *\n * * * * * *\n * * B * * S * B *\n * * o * * c * o *\n * * r * Content * r * r *\n * * d * * o * d *\n * * e * * l * e *\n * * r ******************** l * r *\n * * * Scroll * *\n * * ************************** *\n * * Border *\n * **************************************\n *\n */\n/**\n * Get visible area of element\n */\nfunction getVisibleArea(initArea, scrollerList) {\n var visibleArea = _objectSpread2({}, initArea);\n (scrollerList || []).forEach(function (ele) {\n if (ele instanceof HTMLBodyElement) {\n return;\n }\n\n // Skip if static position which will not affect visible area\n var _getWin$getComputedSt2 = getWin(ele).getComputedStyle(ele),\n overflow = _getWin$getComputedSt2.overflow,\n overflowClipMargin = _getWin$getComputedSt2.overflowClipMargin,\n borderTopWidth = _getWin$getComputedSt2.borderTopWidth,\n borderBottomWidth = _getWin$getComputedSt2.borderBottomWidth,\n borderLeftWidth = _getWin$getComputedSt2.borderLeftWidth,\n borderRightWidth = _getWin$getComputedSt2.borderRightWidth;\n var eleRect = ele.getBoundingClientRect();\n var eleOutHeight = ele.offsetHeight,\n eleInnerHeight = ele.clientHeight,\n eleOutWidth = ele.offsetWidth,\n eleInnerWidth = ele.clientWidth;\n var borderTopNum = getPxValue(borderTopWidth);\n var borderBottomNum = getPxValue(borderBottomWidth);\n var borderLeftNum = getPxValue(borderLeftWidth);\n var borderRightNum = getPxValue(borderRightWidth);\n var scaleX = toNum(Math.round(eleRect.width / eleOutWidth * 1000) / 1000);\n var scaleY = toNum(Math.round(eleRect.height / eleOutHeight * 1000) / 1000);\n\n // Original visible area\n var eleScrollWidth = (eleOutWidth - eleInnerWidth - borderLeftNum - borderRightNum) * scaleX;\n var eleScrollHeight = (eleOutHeight - eleInnerHeight - borderTopNum - borderBottomNum) * scaleY;\n\n // Cut border size\n var scaledBorderTopWidth = borderTopNum * scaleY;\n var scaledBorderBottomWidth = borderBottomNum * scaleY;\n var scaledBorderLeftWidth = borderLeftNum * scaleX;\n var scaledBorderRightWidth = borderRightNum * scaleX;\n\n // Clip margin\n var clipMarginWidth = 0;\n var clipMarginHeight = 0;\n if (overflow === \'clip\') {\n var clipNum = getPxValue(overflowClipMargin);\n clipMarginWidth = clipNum * scaleX;\n clipMarginHeight = clipNum * scaleY;\n }\n\n // Region\n var eleLeft = eleRect.x + scaledBorderLeftWidth - clipMarginWidth;\n var eleTop = eleRect.y + scaledBorderTopWidth - clipMarginHeight;\n var eleRight = eleLeft + eleRect.width + 2 * clipMarginWidth - scaledBorderLeftWidth - scaledBorderRightWidth - eleScrollWidth;\n var eleBottom = eleTop + eleRect.height + 2 * clipMarginHeight - scaledBorderTopWidth - scaledBorderBottomWidth - eleScrollHeight;\n visibleArea.left = Math.max(visibleArea.left, eleLeft);\n visibleArea.top = Math.max(visibleArea.top, eleTop);\n visibleArea.right = Math.min(visibleArea.right, eleRight);\n visibleArea.bottom = Math.min(visibleArea.bottom, eleBottom);\n });\n return visibleArea;\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useAlign.js\n\n\n\n\n\n\n\n\nfunction getUnitOffset(size) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var offsetStr = "".concat(offset);\n var cells = offsetStr.match(/^(.*)\\%$/);\n if (cells) {\n return size * (parseFloat(cells[1]) / 100);\n }\n return parseFloat(offsetStr);\n}\nfunction getNumberOffset(rect, offset) {\n var _ref = offset || [],\n _ref2 = slicedToArray_slicedToArray(_ref, 2),\n offsetX = _ref2[0],\n offsetY = _ref2[1];\n return [getUnitOffset(rect.width, offsetX), getUnitOffset(rect.height, offsetY)];\n}\nfunction splitPoints() {\n var points = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : \'\';\n return [points[0], points[1]];\n}\nfunction getAlignPoint(rect, points) {\n var topBottom = points[0];\n var leftRight = points[1];\n var x;\n var y;\n\n // Top & Bottom\n if (topBottom === \'t\') {\n y = rect.y;\n } else if (topBottom === \'b\') {\n y = rect.y + rect.height;\n } else {\n y = rect.y + rect.height / 2;\n }\n\n // Left & Right\n if (leftRight === \'l\') {\n x = rect.x;\n } else if (leftRight === \'r\') {\n x = rect.x + rect.width;\n } else {\n x = rect.x + rect.width / 2;\n }\n return {\n x: x,\n y: y\n };\n}\nfunction reversePoints(points, index) {\n var reverseMap = {\n t: \'b\',\n b: \'t\',\n l: \'r\',\n r: \'l\'\n };\n return points.map(function (point, i) {\n if (i === index) {\n return reverseMap[point] || \'c\';\n }\n return point;\n }).join(\'\');\n}\nfunction useAlign(open, popupEle, target, placement, builtinPlacements, popupAlign, onPopupAlign) {\n var _React$useState = react.useState({\n ready: false,\n offsetX: 0,\n offsetY: 0,\n arrowX: 0,\n arrowY: 0,\n scaleX: 1,\n scaleY: 1,\n align: builtinPlacements[placement] || {}\n }),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n offsetInfo = _React$useState2[0],\n setOffsetInfo = _React$useState2[1];\n var alignCountRef = react.useRef(0);\n var scrollerList = react.useMemo(function () {\n if (!popupEle) {\n return [];\n }\n return collectScroller(popupEle);\n }, [popupEle]);\n\n // ========================= Flip ==========================\n // We will memo flip info.\n // If size change to make flip, it will memo the flip info and use it in next align.\n var prevFlipRef = react.useRef({});\n var resetFlipCache = function resetFlipCache() {\n prevFlipRef.current = {};\n };\n if (!open) {\n resetFlipCache();\n }\n\n // ========================= Align =========================\n var onAlign = useEvent(function () {\n if (popupEle && target && open) {\n var popupElement = popupEle;\n var originLeft = popupElement.style.left;\n var originTop = popupElement.style.top;\n var doc = popupElement.ownerDocument;\n var win = getWin(popupElement);\n\n // Placement\n var placementInfo = _objectSpread2(_objectSpread2({}, builtinPlacements[placement]), popupAlign);\n\n // Reset first\n popupElement.style.left = \'0\';\n popupElement.style.top = \'0\';\n\n // Calculate align style, we should consider `transform` case\n var targetRect;\n if (Array.isArray(target)) {\n targetRect = {\n x: target[0],\n y: target[1],\n width: 0,\n height: 0\n };\n } else {\n var rect = target.getBoundingClientRect();\n targetRect = {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height\n };\n }\n var popupRect = popupElement.getBoundingClientRect();\n var _win$getComputedStyle = win.getComputedStyle(popupElement),\n width = _win$getComputedStyle.width,\n height = _win$getComputedStyle.height;\n var _doc$documentElement = doc.documentElement,\n clientWidth = _doc$documentElement.clientWidth,\n clientHeight = _doc$documentElement.clientHeight,\n scrollWidth = _doc$documentElement.scrollWidth,\n scrollHeight = _doc$documentElement.scrollHeight,\n scrollTop = _doc$documentElement.scrollTop,\n scrollLeft = _doc$documentElement.scrollLeft;\n var popupHeight = popupRect.height;\n var popupWidth = popupRect.width;\n var targetHeight = targetRect.height;\n var targetWidth = targetRect.width;\n\n // Get bounding of visible area\n var visibleArea = placementInfo.htmlRegion === \'scroll\' ?\n // Scroll region should take scrollLeft & scrollTop into account\n {\n left: -scrollLeft,\n top: -scrollTop,\n right: scrollWidth - scrollLeft,\n bottom: scrollHeight - scrollTop\n } : {\n left: 0,\n top: 0,\n right: clientWidth,\n bottom: clientHeight\n };\n visibleArea = getVisibleArea(visibleArea, scrollerList);\n\n // Reset back\n popupElement.style.left = originLeft;\n popupElement.style.top = originTop;\n\n // Calculate scale\n var _scaleX = toNum(Math.round(popupWidth / parseFloat(width) * 1000) / 1000);\n var _scaleY = toNum(Math.round(popupHeight / parseFloat(height) * 1000) / 1000);\n\n // No need to align since it\'s not visible in view\n if (_scaleX === 0 || _scaleY === 0 || isDOM(target) && !isVisible(target)) {\n return;\n }\n\n // Offset\n var offset = placementInfo.offset,\n targetOffset = placementInfo.targetOffset;\n var _getNumberOffset = getNumberOffset(popupRect, offset),\n _getNumberOffset2 = slicedToArray_slicedToArray(_getNumberOffset, 2),\n popupOffsetX = _getNumberOffset2[0],\n popupOffsetY = _getNumberOffset2[1];\n var _getNumberOffset3 = getNumberOffset(targetRect, targetOffset),\n _getNumberOffset4 = slicedToArray_slicedToArray(_getNumberOffset3, 2),\n targetOffsetX = _getNumberOffset4[0],\n targetOffsetY = _getNumberOffset4[1];\n targetRect.x -= targetOffsetX;\n targetRect.y -= targetOffsetY;\n\n // Points\n var _ref3 = placementInfo.points || [],\n _ref4 = slicedToArray_slicedToArray(_ref3, 2),\n popupPoint = _ref4[0],\n targetPoint = _ref4[1];\n var targetPoints = splitPoints(targetPoint);\n var popupPoints = splitPoints(popupPoint);\n var targetAlignPoint = getAlignPoint(targetRect, targetPoints);\n var popupAlignPoint = getAlignPoint(popupRect, popupPoints);\n\n // Real align info may not same as origin one\n var nextAlignInfo = _objectSpread2({}, placementInfo);\n\n // Next Offset\n var nextOffsetX = targetAlignPoint.x - popupAlignPoint.x + popupOffsetX;\n var nextOffsetY = targetAlignPoint.y - popupAlignPoint.y + popupOffsetY;\n\n // ============== Intersection ===============\n // Get area by position. Used for check if flip area is better\n function getIntersectionVisibleArea(offsetX, offsetY) {\n var l = popupRect.x + offsetX;\n var t = popupRect.y + offsetY;\n var r = l + popupWidth;\n var b = t + popupHeight;\n var visibleL = Math.max(l, visibleArea.left);\n var visibleT = Math.max(t, visibleArea.top);\n var visibleR = Math.min(r, visibleArea.right);\n var visibleB = Math.min(b, visibleArea.bottom);\n return Math.max(0, (visibleR - visibleL) * (visibleB - visibleT));\n }\n var originIntersectionVisibleArea = getIntersectionVisibleArea(nextOffsetX, nextOffsetY);\n\n // ========================== Overflow ===========================\n var targetAlignPointTL = getAlignPoint(targetRect, [\'t\', \'l\']);\n var popupAlignPointTL = getAlignPoint(popupRect, [\'t\', \'l\']);\n var targetAlignPointBR = getAlignPoint(targetRect, [\'b\', \'r\']);\n var popupAlignPointBR = getAlignPoint(popupRect, [\'b\', \'r\']);\n var overflow = placementInfo.overflow || {};\n var adjustX = overflow.adjustX,\n adjustY = overflow.adjustY,\n shiftX = overflow.shiftX,\n shiftY = overflow.shiftY;\n var supportAdjust = function supportAdjust(val) {\n if (typeof val === \'boolean\') {\n return val;\n }\n return val >= 0;\n };\n\n // Prepare position\n var nextPopupY;\n var nextPopupBottom;\n var nextPopupX;\n var nextPopupRight;\n function syncNextPopupPosition() {\n nextPopupY = popupRect.y + nextOffsetY;\n nextPopupBottom = nextPopupY + popupHeight;\n nextPopupX = popupRect.x + nextOffsetX;\n nextPopupRight = nextPopupX + popupWidth;\n }\n syncNextPopupPosition();\n\n // >>>>>>>>>> Top & Bottom\n var needAdjustY = supportAdjust(adjustY);\n var sameTB = popupPoints[0] === targetPoints[0];\n\n // Bottom to Top\n if (needAdjustY && popupPoints[0] === \'t\' && (nextPopupBottom > visibleArea.bottom || prevFlipRef.current.bt)) {\n var tmpNextOffsetY = nextOffsetY;\n if (sameTB) {\n tmpNextOffsetY -= popupHeight - targetHeight;\n } else {\n tmpNextOffsetY = targetAlignPointTL.y - popupAlignPointBR.y - popupOffsetY;\n }\n if (getIntersectionVisibleArea(nextOffsetX, tmpNextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.bt = true;\n nextOffsetY = tmpNextOffsetY;\n nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];\n } else {\n prevFlipRef.current.bt = false;\n }\n }\n\n // Top to Bottom\n if (needAdjustY && popupPoints[0] === \'b\' && (nextPopupY < visibleArea.top || prevFlipRef.current.tb)) {\n var _tmpNextOffsetY = nextOffsetY;\n if (sameTB) {\n _tmpNextOffsetY += popupHeight - targetHeight;\n } else {\n _tmpNextOffsetY = targetAlignPointBR.y - popupAlignPointTL.y - popupOffsetY;\n }\n if (getIntersectionVisibleArea(nextOffsetX, _tmpNextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.tb = true;\n nextOffsetY = _tmpNextOffsetY;\n nextAlignInfo.points = [reversePoints(popupPoints, 0), reversePoints(targetPoints, 0)];\n } else {\n prevFlipRef.current.tb = false;\n }\n }\n\n // >>>>>>>>>> Left & Right\n var needAdjustX = supportAdjust(adjustX);\n\n // >>>>> Flip\n var sameLR = popupPoints[1] === targetPoints[1];\n\n // Right to Left\n if (needAdjustX && popupPoints[1] === \'l\' && (nextPopupRight > visibleArea.right || prevFlipRef.current.rl)) {\n var tmpNextOffsetX = nextOffsetX;\n if (sameLR) {\n tmpNextOffsetX -= popupWidth - targetWidth;\n } else {\n tmpNextOffsetX = targetAlignPointTL.x - popupAlignPointBR.x - popupOffsetX;\n }\n if (getIntersectionVisibleArea(tmpNextOffsetX, nextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.rl = true;\n nextOffsetX = tmpNextOffsetX;\n nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];\n } else {\n prevFlipRef.current.rl = false;\n }\n }\n\n // Left to Right\n if (needAdjustX && popupPoints[1] === \'r\' && (nextPopupX < visibleArea.left || prevFlipRef.current.lr)) {\n var _tmpNextOffsetX = nextOffsetX;\n if (sameLR) {\n _tmpNextOffsetX += popupWidth - targetWidth;\n } else {\n _tmpNextOffsetX = targetAlignPointBR.x - popupAlignPointTL.x - popupOffsetX;\n }\n if (getIntersectionVisibleArea(_tmpNextOffsetX, nextOffsetY) >= originIntersectionVisibleArea) {\n prevFlipRef.current.lr = true;\n nextOffsetX = _tmpNextOffsetX;\n nextAlignInfo.points = [reversePoints(popupPoints, 1), reversePoints(targetPoints, 1)];\n } else {\n prevFlipRef.current.lr = false;\n }\n }\n\n // ============================ Shift ============================\n syncNextPopupPosition();\n var numShiftX = shiftX === true ? 0 : shiftX;\n if (typeof numShiftX === \'number\') {\n // Left\n if (nextPopupX < visibleArea.left) {\n nextOffsetX -= nextPopupX - visibleArea.left;\n if (targetRect.x + targetWidth < visibleArea.left + numShiftX) {\n nextOffsetX += targetRect.x - visibleArea.left + targetWidth - numShiftX;\n }\n }\n\n // Right\n if (nextPopupRight > visibleArea.right) {\n nextOffsetX -= nextPopupRight - visibleArea.right;\n if (targetRect.x > visibleArea.right - numShiftX) {\n nextOffsetX += targetRect.x - visibleArea.right + numShiftX;\n }\n }\n }\n var numShiftY = shiftY === true ? 0 : shiftY;\n if (typeof numShiftY === \'number\') {\n // Top\n if (nextPopupY < visibleArea.top) {\n nextOffsetY -= nextPopupY - visibleArea.top;\n if (targetRect.y + targetHeight < visibleArea.top + numShiftY) {\n nextOffsetY += targetRect.y - visibleArea.top + targetHeight - numShiftY;\n }\n }\n\n // Bottom\n if (nextPopupBottom > visibleArea.bottom) {\n nextOffsetY -= nextPopupBottom - visibleArea.bottom;\n if (targetRect.y > visibleArea.bottom - numShiftY) {\n nextOffsetY += targetRect.y - visibleArea.bottom + numShiftY;\n }\n }\n }\n\n // ============================ Arrow ============================\n // Arrow center align\n var popupLeft = popupRect.x + nextOffsetX;\n var popupRight = popupLeft + popupWidth;\n var popupTop = popupRect.y + nextOffsetY;\n var popupBottom = popupTop + popupHeight;\n var targetLeft = targetRect.x;\n var targetRight = targetLeft + targetWidth;\n var targetTop = targetRect.y;\n var targetBottom = targetTop + targetHeight;\n var maxLeft = Math.max(popupLeft, targetLeft);\n var minRight = Math.min(popupRight, targetRight);\n var xCenter = (maxLeft + minRight) / 2;\n var nextArrowX = xCenter - popupLeft;\n var maxTop = Math.max(popupTop, targetTop);\n var minBottom = Math.min(popupBottom, targetBottom);\n var yCenter = (maxTop + minBottom) / 2;\n var nextArrowY = yCenter - popupTop;\n onPopupAlign === null || onPopupAlign === void 0 ? void 0 : onPopupAlign(popupEle, nextAlignInfo);\n setOffsetInfo({\n ready: true,\n offsetX: nextOffsetX / _scaleX,\n offsetY: nextOffsetY / _scaleY,\n arrowX: nextArrowX / _scaleX,\n arrowY: nextArrowY / _scaleY,\n scaleX: _scaleX,\n scaleY: _scaleY,\n align: nextAlignInfo\n });\n }\n });\n var triggerAlign = function triggerAlign() {\n alignCountRef.current += 1;\n var id = alignCountRef.current;\n\n // Merge all align requirement into one frame\n Promise.resolve().then(function () {\n if (alignCountRef.current === id) {\n onAlign();\n }\n });\n };\n\n // Reset ready status when placement & open changed\n var resetReady = function resetReady() {\n setOffsetInfo(function (ori) {\n return _objectSpread2(_objectSpread2({}, ori), {}, {\n ready: false\n });\n });\n };\n hooks_useLayoutEffect(resetReady, [placement]);\n hooks_useLayoutEffect(function () {\n if (!open) {\n resetReady();\n }\n }, [open]);\n return [offsetInfo.ready, offsetInfo.offsetX, offsetInfo.offsetY, offsetInfo.arrowX, offsetInfo.arrowY, offsetInfo.scaleX, offsetInfo.scaleY, offsetInfo.align, triggerAlign];\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/hooks/useWatch.js\n\n\n\nfunction useWatch(open, target, popup, onAlign) {\n hooks_useLayoutEffect(function () {\n if (open && target && popup) {\n var targetElement = target;\n var popupElement = popup;\n var targetScrollList = collectScroller(targetElement);\n var popupScrollList = collectScroller(popupElement);\n var win = getWin(popupElement);\n var mergedList = new Set([win].concat(_toConsumableArray(targetScrollList), _toConsumableArray(popupScrollList)));\n function notifyScroll() {\n onAlign();\n }\n mergedList.forEach(function (scroller) {\n scroller.addEventListener(\'scroll\', notifyScroll, {\n passive: true\n });\n });\n win.addEventListener(\'resize\', notifyScroll, {\n passive: true\n });\n\n // First time always do align\n onAlign();\n return function () {\n mergedList.forEach(function (scroller) {\n scroller.removeEventListener(\'scroll\', notifyScroll);\n win.removeEventListener(\'resize\', notifyScroll);\n });\n };\n }\n }, [open, target, popup]);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/context.js\n\nvar context_excluded = (/* unused pure expression or super */ null && (["children"]));\n\nvar context_Context = /*#__PURE__*/react.createContext({});\nfunction MotionProvider(_ref) {\n var children = _ref.children,\n props = _objectWithoutProperties(_ref, context_excluded);\n return /*#__PURE__*/React.createElement(context_Context.Provider, {\n value: props\n }, children);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/DomWrapper.js\n\n\n\n\n\nvar DomWrapper_DomWrapper = /*#__PURE__*/function (_React$Component) {\n _inherits(DomWrapper, _React$Component);\n var _super = _createSuper(DomWrapper);\n function DomWrapper() {\n classCallCheck_classCallCheck(this, DomWrapper);\n return _super.apply(this, arguments);\n }\n createClass_createClass(DomWrapper, [{\n key: "render",\n value: function render() {\n return this.props.children;\n }\n }]);\n return DomWrapper;\n}(react.Component);\n/* harmony default export */ const es_DomWrapper = (DomWrapper_DomWrapper);\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/interface.js\nvar STATUS_NONE = \'none\';\nvar STATUS_APPEAR = \'appear\';\nvar STATUS_ENTER = \'enter\';\nvar STATUS_LEAVE = \'leave\';\nvar STEP_NONE = \'none\';\nvar STEP_PREPARE = \'prepare\';\nvar STEP_START = \'start\';\nvar STEP_ACTIVE = \'active\';\nvar STEP_ACTIVATED = \'end\';\n/**\n * Used for disabled motion case.\n * Prepare stage will still work but start & active will be skipped.\n */\nvar STEP_PREPARED = \'prepared\';\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/util/motion.js\n\n\n// ================= Transition =================\n// Event wrapper. Copy from react source code\nfunction makePrefixMap(styleProp, eventName) {\n var prefixes = {};\n prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();\n prefixes["Webkit".concat(styleProp)] = "webkit".concat(eventName);\n prefixes["Moz".concat(styleProp)] = "moz".concat(eventName);\n prefixes["ms".concat(styleProp)] = "MS".concat(eventName);\n prefixes["O".concat(styleProp)] = "o".concat(eventName.toLowerCase());\n return prefixes;\n}\nfunction getVendorPrefixes(domSupport, win) {\n var prefixes = {\n animationend: makePrefixMap(\'Animation\', \'AnimationEnd\'),\n transitionend: makePrefixMap(\'Transition\', \'TransitionEnd\')\n };\n if (domSupport) {\n if (!(\'AnimationEvent\' in win)) {\n delete prefixes.animationend.animation;\n }\n if (!(\'TransitionEvent\' in win)) {\n delete prefixes.transitionend.transition;\n }\n }\n return prefixes;\n}\nvar vendorPrefixes = getVendorPrefixes(canUseDom(), typeof window !== \'undefined\' ? window : {});\nvar style = {};\nif (canUseDom()) {\n var _document$createEleme = document.createElement(\'div\');\n style = _document$createEleme.style;\n}\nvar prefixedEventNames = {};\nfunction getVendorPrefixedEventName(eventName) {\n if (prefixedEventNames[eventName]) {\n return prefixedEventNames[eventName];\n }\n var prefixMap = vendorPrefixes[eventName];\n if (prefixMap) {\n var stylePropList = Object.keys(prefixMap);\n var len = stylePropList.length;\n for (var i = 0; i < len; i += 1) {\n var styleProp = stylePropList[i];\n if (Object.prototype.hasOwnProperty.call(prefixMap, styleProp) && styleProp in style) {\n prefixedEventNames[eventName] = prefixMap[styleProp];\n return prefixedEventNames[eventName];\n }\n }\n }\n return \'\';\n}\nvar internalAnimationEndName = getVendorPrefixedEventName(\'animationend\');\nvar internalTransitionEndName = getVendorPrefixedEventName(\'transitionend\');\nvar supportTransition = !!(internalAnimationEndName && internalTransitionEndName);\nvar animationEndName = internalAnimationEndName || \'animationend\';\nvar transitionEndName = internalTransitionEndName || \'transitionend\';\nfunction getTransitionName(transitionName, transitionType) {\n if (!transitionName) return null;\n if (typeof_typeof(transitionName) === \'object\') {\n var type = transitionType.replace(/-\\w/g, function (match) {\n return match[1].toUpperCase();\n });\n return transitionName[type];\n }\n return "".concat(transitionName, "-").concat(transitionType);\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useDomMotionEvents.js\n\n\n\n/* harmony default export */ const useDomMotionEvents = (function (callback) {\n var cacheElementRef = (0,react.useRef)();\n\n // Cache callback\n var callbackRef = (0,react.useRef)(callback);\n callbackRef.current = callback;\n\n // Internal motion event handler\n var onInternalMotionEnd = react.useCallback(function (event) {\n callbackRef.current(event);\n }, []);\n\n // Remove events\n function removeMotionEvents(element) {\n if (element) {\n element.removeEventListener(transitionEndName, onInternalMotionEnd);\n element.removeEventListener(animationEndName, onInternalMotionEnd);\n }\n }\n\n // Patch events\n function patchMotionEvents(element) {\n if (cacheElementRef.current && cacheElementRef.current !== element) {\n removeMotionEvents(cacheElementRef.current);\n }\n if (element && element !== cacheElementRef.current) {\n element.addEventListener(transitionEndName, onInternalMotionEnd);\n element.addEventListener(animationEndName, onInternalMotionEnd);\n\n // Save as cache in case dom removed trigger by `motionDeadline`\n cacheElementRef.current = element;\n }\n }\n\n // Clean up when removed\n react.useEffect(function () {\n return function () {\n removeMotionEvents(cacheElementRef.current);\n };\n }, []);\n return [patchMotionEvents, removeMotionEvents];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useIsomorphicLayoutEffect.js\n\n\n\n// It\'s safe to use `useLayoutEffect` but the warning is annoying\nvar useIsomorphicLayoutEffect = canUseDom() ? react.useLayoutEffect : react.useEffect;\n/* harmony default export */ const hooks_useIsomorphicLayoutEffect = (useIsomorphicLayoutEffect);\n;// CONCATENATED MODULE: ./node_modules/rc-util/es/raf.js\nvar raf_raf = function raf(callback) {\n return +setTimeout(callback, 16);\n};\nvar caf = function caf(num) {\n return clearTimeout(num);\n};\nif (typeof window !== \'undefined\' && \'requestAnimationFrame\' in window) {\n raf_raf = function raf(callback) {\n return window.requestAnimationFrame(callback);\n };\n caf = function caf(handle) {\n return window.cancelAnimationFrame(handle);\n };\n}\nvar rafUUID = 0;\nvar rafIds = new Map();\nfunction cleanup(id) {\n rafIds.delete(id);\n}\nvar wrapperRaf = function wrapperRaf(callback) {\n var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n rafUUID += 1;\n var id = rafUUID;\n function callRef(leftTimes) {\n if (leftTimes === 0) {\n // Clean up\n cleanup(id);\n\n // Trigger\n callback();\n } else {\n // Next raf\n var realId = raf_raf(function () {\n callRef(leftTimes - 1);\n });\n\n // Bind real raf id\n rafIds.set(id, realId);\n }\n }\n callRef(times);\n return id;\n};\nwrapperRaf.cancel = function (id) {\n var realId = rafIds.get(id);\n cleanup(realId);\n return caf(realId);\n};\n/* harmony default export */ const es_raf = (wrapperRaf);\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useNextFrame.js\n\n\n/* harmony default export */ const useNextFrame = (function () {\n var nextFrameRef = react.useRef(null);\n function cancelNextFrame() {\n es_raf.cancel(nextFrameRef.current);\n }\n function nextFrame(callback) {\n var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;\n cancelNextFrame();\n var nextFrameId = es_raf(function () {\n if (delay <= 1) {\n callback({\n isCanceled: function isCanceled() {\n return nextFrameId !== nextFrameRef.current;\n }\n });\n } else {\n nextFrame(callback, delay - 1);\n }\n });\n nextFrameRef.current = nextFrameId;\n }\n react.useEffect(function () {\n return function () {\n cancelNextFrame();\n };\n }, []);\n return [nextFrame, cancelNextFrame];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useStepQueue.js\n\n\n\n\n\n\nvar FULL_STEP_QUEUE = [STEP_PREPARE, STEP_START, STEP_ACTIVE, STEP_ACTIVATED];\nvar SIMPLE_STEP_QUEUE = [STEP_PREPARE, STEP_PREPARED];\n\n/** Skip current step */\nvar SkipStep = false;\n/** Current step should be update in */\nvar DoStep = true;\nfunction isActive(step) {\n return step === STEP_ACTIVE || step === STEP_ACTIVATED;\n}\n/* harmony default export */ const useStepQueue = (function (status, prepareOnly, callback) {\n var _useState = useSafeState(STEP_NONE),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n step = _useState2[0],\n setStep = _useState2[1];\n var _useNextFrame = useNextFrame(),\n _useNextFrame2 = slicedToArray_slicedToArray(_useNextFrame, 2),\n nextFrame = _useNextFrame2[0],\n cancelNextFrame = _useNextFrame2[1];\n function startQueue() {\n setStep(STEP_PREPARE, true);\n }\n var STEP_QUEUE = prepareOnly ? SIMPLE_STEP_QUEUE : FULL_STEP_QUEUE;\n hooks_useIsomorphicLayoutEffect(function () {\n if (step !== STEP_NONE && step !== STEP_ACTIVATED) {\n var index = STEP_QUEUE.indexOf(step);\n var nextStep = STEP_QUEUE[index + 1];\n var result = callback(step);\n if (result === SkipStep) {\n // Skip when no needed\n setStep(nextStep, true);\n } else if (nextStep) {\n // Do as frame for step update\n nextFrame(function (info) {\n function doNext() {\n // Skip since current queue is ood\n if (info.isCanceled()) return;\n setStep(nextStep, true);\n }\n if (result === true) {\n doNext();\n } else {\n // Only promise should be async\n Promise.resolve(result).then(doNext);\n }\n });\n }\n }\n }, [status, step]);\n react.useEffect(function () {\n return function () {\n cancelNextFrame();\n };\n }, []);\n return [startQueue, step];\n});\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/hooks/useStatus.js\n\n\n\n\n\n\n\n\n\n\nfunction useStatus(supportMotion, visible, getElement, _ref) {\n var _ref$motionEnter = _ref.motionEnter,\n motionEnter = _ref$motionEnter === void 0 ? true : _ref$motionEnter,\n _ref$motionAppear = _ref.motionAppear,\n motionAppear = _ref$motionAppear === void 0 ? true : _ref$motionAppear,\n _ref$motionLeave = _ref.motionLeave,\n motionLeave = _ref$motionLeave === void 0 ? true : _ref$motionLeave,\n motionDeadline = _ref.motionDeadline,\n motionLeaveImmediately = _ref.motionLeaveImmediately,\n onAppearPrepare = _ref.onAppearPrepare,\n onEnterPrepare = _ref.onEnterPrepare,\n onLeavePrepare = _ref.onLeavePrepare,\n onAppearStart = _ref.onAppearStart,\n onEnterStart = _ref.onEnterStart,\n onLeaveStart = _ref.onLeaveStart,\n onAppearActive = _ref.onAppearActive,\n onEnterActive = _ref.onEnterActive,\n onLeaveActive = _ref.onLeaveActive,\n onAppearEnd = _ref.onAppearEnd,\n onEnterEnd = _ref.onEnterEnd,\n onLeaveEnd = _ref.onLeaveEnd,\n onVisibleChanged = _ref.onVisibleChanged;\n // Used for outer render usage to avoid `visible: false & status: none` to render nothing\n var _useState = useSafeState(),\n _useState2 = slicedToArray_slicedToArray(_useState, 2),\n asyncVisible = _useState2[0],\n setAsyncVisible = _useState2[1];\n var _useState3 = useSafeState(STATUS_NONE),\n _useState4 = slicedToArray_slicedToArray(_useState3, 2),\n status = _useState4[0],\n setStatus = _useState4[1];\n var _useState5 = useSafeState(null),\n _useState6 = slicedToArray_slicedToArray(_useState5, 2),\n style = _useState6[0],\n setStyle = _useState6[1];\n var mountedRef = (0,react.useRef)(false);\n var deadlineRef = (0,react.useRef)(null);\n\n // =========================== Dom Node ===========================\n function getDomElement() {\n return getElement();\n }\n\n // ========================== Motion End ==========================\n var activeRef = (0,react.useRef)(false);\n\n /**\n * Clean up status & style\n */\n function updateMotionEndStatus() {\n setStatus(STATUS_NONE, true);\n setStyle(null, true);\n }\n function onInternalMotionEnd(event) {\n var element = getDomElement();\n if (event && !event.deadline && event.target !== element) {\n // event exists\n // not initiated by deadline\n // transitionEnd not fired by inner elements\n return;\n }\n var currentActive = activeRef.current;\n var canEnd;\n if (status === STATUS_APPEAR && currentActive) {\n canEnd = onAppearEnd === null || onAppearEnd === void 0 ? void 0 : onAppearEnd(element, event);\n } else if (status === STATUS_ENTER && currentActive) {\n canEnd = onEnterEnd === null || onEnterEnd === void 0 ? void 0 : onEnterEnd(element, event);\n } else if (status === STATUS_LEAVE && currentActive) {\n canEnd = onLeaveEnd === null || onLeaveEnd === void 0 ? void 0 : onLeaveEnd(element, event);\n }\n\n // Only update status when `canEnd` and not destroyed\n if (status !== STATUS_NONE && currentActive && canEnd !== false) {\n updateMotionEndStatus();\n }\n }\n var _useDomMotionEvents = useDomMotionEvents(onInternalMotionEnd),\n _useDomMotionEvents2 = slicedToArray_slicedToArray(_useDomMotionEvents, 1),\n patchMotionEvents = _useDomMotionEvents2[0];\n\n // ============================= Step =============================\n var getEventHandlers = function getEventHandlers(targetStatus) {\n var _ref2, _ref3, _ref4;\n switch (targetStatus) {\n case STATUS_APPEAR:\n return _ref2 = {}, _defineProperty(_ref2, STEP_PREPARE, onAppearPrepare), _defineProperty(_ref2, STEP_START, onAppearStart), _defineProperty(_ref2, STEP_ACTIVE, onAppearActive), _ref2;\n case STATUS_ENTER:\n return _ref3 = {}, _defineProperty(_ref3, STEP_PREPARE, onEnterPrepare), _defineProperty(_ref3, STEP_START, onEnterStart), _defineProperty(_ref3, STEP_ACTIVE, onEnterActive), _ref3;\n case STATUS_LEAVE:\n return _ref4 = {}, _defineProperty(_ref4, STEP_PREPARE, onLeavePrepare), _defineProperty(_ref4, STEP_START, onLeaveStart), _defineProperty(_ref4, STEP_ACTIVE, onLeaveActive), _ref4;\n default:\n return {};\n }\n };\n var eventHandlers = react.useMemo(function () {\n return getEventHandlers(status);\n }, [status]);\n var _useStepQueue = useStepQueue(status, !supportMotion, function (newStep) {\n // Only prepare step can be skip\n if (newStep === STEP_PREPARE) {\n var onPrepare = eventHandlers[STEP_PREPARE];\n if (!onPrepare) {\n return SkipStep;\n }\n return onPrepare(getDomElement());\n }\n\n // Rest step is sync update\n if (step in eventHandlers) {\n var _eventHandlers$step;\n setStyle(((_eventHandlers$step = eventHandlers[step]) === null || _eventHandlers$step === void 0 ? void 0 : _eventHandlers$step.call(eventHandlers, getDomElement(), null)) || null);\n }\n if (step === STEP_ACTIVE) {\n // Patch events when motion needed\n patchMotionEvents(getDomElement());\n if (motionDeadline > 0) {\n clearTimeout(deadlineRef.current);\n deadlineRef.current = setTimeout(function () {\n onInternalMotionEnd({\n deadline: true\n });\n }, motionDeadline);\n }\n }\n if (step === STEP_PREPARED) {\n updateMotionEndStatus();\n }\n return DoStep;\n }),\n _useStepQueue2 = slicedToArray_slicedToArray(_useStepQueue, 2),\n startStep = _useStepQueue2[0],\n step = _useStepQueue2[1];\n var active = isActive(step);\n activeRef.current = active;\n\n // ============================ Status ============================\n // Update with new status\n hooks_useIsomorphicLayoutEffect(function () {\n setAsyncVisible(visible);\n var isMounted = mountedRef.current;\n mountedRef.current = true;\n\n // if (!supportMotion) {\n // return;\n // }\n\n var nextStatus;\n\n // Appear\n if (!isMounted && visible && motionAppear) {\n nextStatus = STATUS_APPEAR;\n }\n\n // Enter\n if (isMounted && visible && motionEnter) {\n nextStatus = STATUS_ENTER;\n }\n\n // Leave\n if (isMounted && !visible && motionLeave || !isMounted && motionLeaveImmediately && !visible && motionLeave) {\n nextStatus = STATUS_LEAVE;\n }\n var nextEventHandlers = getEventHandlers(nextStatus);\n\n // Update to next status\n if (nextStatus && (supportMotion || nextEventHandlers[STEP_PREPARE])) {\n setStatus(nextStatus);\n startStep();\n } else {\n // Set back in case no motion but prev status has prepare step\n setStatus(STATUS_NONE);\n }\n }, [visible]);\n\n // ============================ Effect ============================\n // Reset when motion changed\n (0,react.useEffect)(function () {\n if (\n // Cancel appear\n status === STATUS_APPEAR && !motionAppear ||\n // Cancel enter\n status === STATUS_ENTER && !motionEnter ||\n // Cancel leave\n status === STATUS_LEAVE && !motionLeave) {\n setStatus(STATUS_NONE);\n }\n }, [motionAppear, motionEnter, motionLeave]);\n (0,react.useEffect)(function () {\n return function () {\n mountedRef.current = false;\n clearTimeout(deadlineRef.current);\n };\n }, []);\n\n // Trigger `onVisibleChanged`\n var firstMountChangeRef = react.useRef(false);\n (0,react.useEffect)(function () {\n // [visible & motion not end] => [!visible & motion end] still need trigger onVisibleChanged\n if (asyncVisible) {\n firstMountChangeRef.current = true;\n }\n if (asyncVisible !== undefined && status === STATUS_NONE) {\n // Skip first render is invisible since it\'s nothing changed\n if (firstMountChangeRef.current || asyncVisible) {\n onVisibleChanged === null || onVisibleChanged === void 0 ? void 0 : onVisibleChanged(asyncVisible);\n }\n firstMountChangeRef.current = true;\n }\n }, [asyncVisible, status]);\n\n // ============================ Styles ============================\n var mergedStyle = style;\n if (eventHandlers[STEP_PREPARE] && step === STEP_START) {\n mergedStyle = _objectSpread2({\n transition: \'none\'\n }, mergedStyle);\n }\n return [status, step, mergedStyle, asyncVisible !== null && asyncVisible !== void 0 ? asyncVisible : visible];\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/CSSMotion.js\n\n\n\n\n/* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */\n\n\n\n\n\n\n\n\n\n\n\n/**\n * `transitionSupport` is used for none transition test case.\n * Default we use browser transition event support check.\n */\nfunction genCSSMotion(config) {\n var transitionSupport = config;\n if (typeof_typeof(config) === \'object\') {\n transitionSupport = config.transitionSupport;\n }\n function isSupportTransition(props, contextMotion) {\n return !!(props.motionName && transitionSupport && contextMotion !== false);\n }\n var CSSMotion = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _props$visible = props.visible,\n visible = _props$visible === void 0 ? true : _props$visible,\n _props$removeOnLeave = props.removeOnLeave,\n removeOnLeave = _props$removeOnLeave === void 0 ? true : _props$removeOnLeave,\n forceRender = props.forceRender,\n children = props.children,\n motionName = props.motionName,\n leavedClassName = props.leavedClassName,\n eventProps = props.eventProps;\n var _React$useContext = react.useContext(context_Context),\n contextMotion = _React$useContext.motion;\n var supportMotion = isSupportTransition(props, contextMotion);\n\n // Ref to the react node, it may be a HTMLElement\n var nodeRef = (0,react.useRef)();\n // Ref to the dom wrapper in case ref can not pass to HTMLElement\n var wrapperNodeRef = (0,react.useRef)();\n function getDomElement() {\n try {\n // Here we\'re avoiding call for findDOMNode since it\'s deprecated\n // in strict mode. We\'re calling it only when node ref is not\n // an instance of DOM HTMLElement. Otherwise use\n // findDOMNode as a final resort\n return nodeRef.current instanceof HTMLElement ? nodeRef.current : findDOMNode(wrapperNodeRef.current);\n } catch (e) {\n // Only happen when `motionDeadline` trigger but element removed.\n return null;\n }\n }\n var _useStatus = useStatus(supportMotion, visible, getDomElement, props),\n _useStatus2 = slicedToArray_slicedToArray(_useStatus, 4),\n status = _useStatus2[0],\n statusStep = _useStatus2[1],\n statusStyle = _useStatus2[2],\n mergedVisible = _useStatus2[3];\n\n // Record whether content has rendered\n // Will return null for un-rendered even when `removeOnLeave={false}`\n var renderedRef = react.useRef(mergedVisible);\n if (mergedVisible) {\n renderedRef.current = true;\n }\n\n // ====================== Refs ======================\n var setNodeRef = react.useCallback(function (node) {\n nodeRef.current = node;\n fillRef(ref, node);\n }, [ref]);\n\n // ===================== Render =====================\n var motionChildren;\n var mergedProps = _objectSpread2(_objectSpread2({}, eventProps), {}, {\n visible: visible\n });\n if (!children) {\n // No children\n motionChildren = null;\n } else if (status === STATUS_NONE) {\n // Stable children\n if (mergedVisible) {\n motionChildren = children(_objectSpread2({}, mergedProps), setNodeRef);\n } else if (!removeOnLeave && renderedRef.current && leavedClassName) {\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n className: leavedClassName\n }), setNodeRef);\n } else if (forceRender || !removeOnLeave && !leavedClassName) {\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n style: {\n display: \'none\'\n }\n }), setNodeRef);\n } else {\n motionChildren = null;\n }\n } else {\n var _classNames;\n // In motion\n var statusSuffix;\n if (statusStep === STEP_PREPARE) {\n statusSuffix = \'prepare\';\n } else if (isActive(statusStep)) {\n statusSuffix = \'active\';\n } else if (statusStep === STEP_START) {\n statusSuffix = \'start\';\n }\n var motionCls = getTransitionName(motionName, "".concat(status, "-").concat(statusSuffix));\n motionChildren = children(_objectSpread2(_objectSpread2({}, mergedProps), {}, {\n className: classnames_default()(getTransitionName(motionName, status), (_classNames = {}, _defineProperty(_classNames, motionCls, motionCls && statusSuffix), _defineProperty(_classNames, motionName, typeof motionName === \'string\'), _classNames)),\n style: statusStyle\n }), setNodeRef);\n }\n\n // Auto inject ref if child node not have `ref` props\n if ( /*#__PURE__*/react.isValidElement(motionChildren) && supportRef(motionChildren)) {\n var _ref = motionChildren,\n originNodeRef = _ref.ref;\n if (!originNodeRef) {\n motionChildren = /*#__PURE__*/react.cloneElement(motionChildren, {\n ref: setNodeRef\n });\n }\n }\n return /*#__PURE__*/react.createElement(es_DomWrapper, {\n ref: wrapperNodeRef\n }, motionChildren);\n });\n CSSMotion.displayName = \'CSSMotion\';\n return CSSMotion;\n}\n/* harmony default export */ const es_CSSMotion = (genCSSMotion(supportTransition));\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/util/diff.js\n\n\nvar STATUS_ADD = \'add\';\nvar STATUS_KEEP = \'keep\';\nvar STATUS_REMOVE = \'remove\';\nvar STATUS_REMOVED = \'removed\';\nfunction wrapKeyToObject(key) {\n var keyObj;\n if (key && typeof_typeof(key) === \'object\' && \'key\' in key) {\n keyObj = key;\n } else {\n keyObj = {\n key: key\n };\n }\n return _objectSpread2(_objectSpread2({}, keyObj), {}, {\n key: String(keyObj.key)\n });\n}\nfunction parseKeys() {\n var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n return keys.map(wrapKeyToObject);\n}\nfunction diffKeys() {\n var prevKeys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];\n var currentKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n var list = [];\n var currentIndex = 0;\n var currentLen = currentKeys.length;\n var prevKeyObjects = parseKeys(prevKeys);\n var currentKeyObjects = parseKeys(currentKeys);\n\n // Check prev keys to insert or keep\n prevKeyObjects.forEach(function (keyObj) {\n var hit = false;\n for (var i = currentIndex; i < currentLen; i += 1) {\n var currentKeyObj = currentKeyObjects[i];\n if (currentKeyObj.key === keyObj.key) {\n // New added keys should add before current key\n if (currentIndex < i) {\n list = list.concat(currentKeyObjects.slice(currentIndex, i).map(function (obj) {\n return _objectSpread2(_objectSpread2({}, obj), {}, {\n status: STATUS_ADD\n });\n }));\n currentIndex = i;\n }\n list.push(_objectSpread2(_objectSpread2({}, currentKeyObj), {}, {\n status: STATUS_KEEP\n }));\n currentIndex += 1;\n hit = true;\n break;\n }\n }\n\n // If not hit, it means key is removed\n if (!hit) {\n list.push(_objectSpread2(_objectSpread2({}, keyObj), {}, {\n status: STATUS_REMOVE\n }));\n }\n });\n\n // Add rest to the list\n if (currentIndex < currentLen) {\n list = list.concat(currentKeyObjects.slice(currentIndex).map(function (obj) {\n return _objectSpread2(_objectSpread2({}, obj), {}, {\n status: STATUS_ADD\n });\n }));\n }\n\n /**\n * Merge same key when it remove and add again:\n * [1 - add, 2 - keep, 1 - remove] -> [1 - keep, 2 - keep]\n */\n var keys = {};\n list.forEach(function (_ref) {\n var key = _ref.key;\n keys[key] = (keys[key] || 0) + 1;\n });\n var duplicatedKeys = Object.keys(keys).filter(function (key) {\n return keys[key] > 1;\n });\n duplicatedKeys.forEach(function (matchKey) {\n // Remove `STATUS_REMOVE` node.\n list = list.filter(function (_ref2) {\n var key = _ref2.key,\n status = _ref2.status;\n return key !== matchKey || status !== STATUS_REMOVE;\n });\n\n // Update `STATUS_ADD` to `STATUS_KEEP`\n list.forEach(function (node) {\n if (node.key === matchKey) {\n // eslint-disable-next-line no-param-reassign\n node.status = STATUS_KEEP;\n }\n });\n });\n return list;\n}\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/CSSMotionList.js\n\n\n\n\n\n\n\n\n\nvar CSSMotionList_excluded = ["component", "children", "onVisibleChanged", "onAllRemoved"],\n _excluded2 = ["status"];\n/* eslint react/prop-types: 0 */\n\n\n\n\nvar MOTION_PROP_NAMES = [\'eventProps\', \'visible\', \'children\', \'motionName\', \'motionAppear\', \'motionEnter\', \'motionLeave\', \'motionLeaveImmediately\', \'motionDeadline\', \'removeOnLeave\', \'leavedClassName\', \'onAppearStart\', \'onAppearActive\', \'onAppearEnd\', \'onEnterStart\', \'onEnterActive\', \'onEnterEnd\', \'onLeaveStart\', \'onLeaveActive\', \'onLeaveEnd\'];\n/**\n * Generate a CSSMotionList component with config\n * @param transitionSupport No need since CSSMotionList no longer depends on transition support\n * @param CSSMotion CSSMotion component\n */\nfunction genCSSMotionList(transitionSupport) {\n var CSSMotion = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : es_CSSMotion;\n var CSSMotionList = /*#__PURE__*/function (_React$Component) {\n _inherits(CSSMotionList, _React$Component);\n var _super = _createSuper(CSSMotionList);\n function CSSMotionList() {\n var _this;\n classCallCheck_classCallCheck(this, CSSMotionList);\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n _this = _super.call.apply(_super, [this].concat(args));\n _defineProperty(_assertThisInitialized(_this), "state", {\n keyEntities: []\n });\n _defineProperty(_assertThisInitialized(_this), "removeKey", function (removeKey) {\n var keyEntities = _this.state.keyEntities;\n var nextKeyEntities = keyEntities.map(function (entity) {\n if (entity.key !== removeKey) return entity;\n return _objectSpread2(_objectSpread2({}, entity), {}, {\n status: STATUS_REMOVED\n });\n });\n _this.setState({\n keyEntities: nextKeyEntities\n });\n return nextKeyEntities.filter(function (_ref) {\n var status = _ref.status;\n return status !== STATUS_REMOVED;\n }).length;\n });\n return _this;\n }\n createClass_createClass(CSSMotionList, [{\n key: "render",\n value: function render() {\n var _this2 = this;\n var keyEntities = this.state.keyEntities;\n var _this$props = this.props,\n component = _this$props.component,\n children = _this$props.children,\n _onVisibleChanged = _this$props.onVisibleChanged,\n onAllRemoved = _this$props.onAllRemoved,\n restProps = objectWithoutProperties_objectWithoutProperties(_this$props, CSSMotionList_excluded);\n var Component = component || react.Fragment;\n var motionProps = {};\n MOTION_PROP_NAMES.forEach(function (prop) {\n motionProps[prop] = restProps[prop];\n delete restProps[prop];\n });\n delete restProps.keys;\n return /*#__PURE__*/react.createElement(Component, restProps, keyEntities.map(function (_ref2) {\n var status = _ref2.status,\n eventProps = objectWithoutProperties_objectWithoutProperties(_ref2, _excluded2);\n var visible = status === STATUS_ADD || status === STATUS_KEEP;\n return /*#__PURE__*/react.createElement(CSSMotion, extends_extends({}, motionProps, {\n key: eventProps.key,\n visible: visible,\n eventProps: eventProps,\n onVisibleChanged: function onVisibleChanged(changedVisible) {\n _onVisibleChanged === null || _onVisibleChanged === void 0 ? void 0 : _onVisibleChanged(changedVisible, {\n key: eventProps.key\n });\n if (!changedVisible) {\n var restKeysCount = _this2.removeKey(eventProps.key);\n if (restKeysCount === 0 && onAllRemoved) {\n onAllRemoved();\n }\n }\n }\n }), children);\n }));\n }\n }], [{\n key: "getDerivedStateFromProps",\n value: function getDerivedStateFromProps(_ref3, _ref4) {\n var keys = _ref3.keys;\n var keyEntities = _ref4.keyEntities;\n var parsedKeyObjects = parseKeys(keys);\n var mixedKeyEntities = diffKeys(keyEntities, parsedKeyObjects);\n return {\n keyEntities: mixedKeyEntities.filter(function (entity) {\n var prevEntity = keyEntities.find(function (_ref5) {\n var key = _ref5.key;\n return entity.key === key;\n });\n\n // Remove if already mark as removed\n if (prevEntity && prevEntity.status === STATUS_REMOVED && entity.status === STATUS_REMOVE) {\n return false;\n }\n return true;\n })\n };\n }\n\n // ZombieJ: Return the count of rest keys. It\'s safe to refactor if need more info.\n }]);\n return CSSMotionList;\n }(react.Component);\n _defineProperty(CSSMotionList, "defaultProps", {\n component: \'div\'\n });\n return CSSMotionList;\n}\n/* harmony default export */ const CSSMotionList = (genCSSMotionList(supportTransition));\n;// CONCATENATED MODULE: ./node_modules/rc-motion/es/index.js\n\n\n\n\n/* harmony default export */ const rc_motion_es = (es_CSSMotion);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/Arrow.js\n\n\nfunction Arrow(props) {\n var prefixCls = props.prefixCls,\n align = props.align,\n arrow = props.arrow,\n arrowPos = props.arrowPos;\n var _ref = arrow || {},\n className = _ref.className,\n content = _ref.content;\n var _arrowPos$x = arrowPos.x,\n x = _arrowPos$x === void 0 ? 0 : _arrowPos$x,\n _arrowPos$y = arrowPos.y,\n y = _arrowPos$y === void 0 ? 0 : _arrowPos$y;\n var arrowRef = react.useRef();\n\n // Skip if no align\n if (!align || !align.points) {\n return null;\n }\n var alignStyle = {\n position: \'absolute\'\n };\n\n // Skip if no need to align\n if (align.autoArrow !== false) {\n var popupPoints = align.points[0];\n var targetPoints = align.points[1];\n var popupTB = popupPoints[0];\n var popupLR = popupPoints[1];\n var targetTB = targetPoints[0];\n var targetLR = targetPoints[1];\n\n // Top & Bottom\n if (popupTB === targetTB || ![\'t\', \'b\'].includes(popupTB)) {\n alignStyle.top = y;\n } else if (popupTB === \'t\') {\n alignStyle.top = 0;\n } else {\n alignStyle.bottom = 0;\n }\n\n // Left & Right\n if (popupLR === targetLR || ![\'l\', \'r\'].includes(popupLR)) {\n alignStyle.left = x;\n } else if (popupLR === \'l\') {\n alignStyle.left = 0;\n } else {\n alignStyle.right = 0;\n }\n }\n return /*#__PURE__*/react.createElement("div", {\n ref: arrowRef,\n className: classnames_default()("".concat(prefixCls, "-arrow"), className),\n style: alignStyle\n }, content);\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/Mask.js\n\n\n\n\nfunction Mask(props) {\n var prefixCls = props.prefixCls,\n open = props.open,\n zIndex = props.zIndex,\n mask = props.mask,\n motion = props.motion;\n if (!mask) {\n return null;\n }\n return /*#__PURE__*/react.createElement(rc_motion_es, extends_extends({}, motion, {\n motionAppear: true,\n visible: open,\n removeOnLeave: true\n }), function (_ref) {\n var className = _ref.className;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n zIndex: zIndex\n },\n className: classnames_default()("".concat(prefixCls, "-mask"), className)\n });\n });\n}\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/PopupContent.js\n\nvar PopupContent = /*#__PURE__*/react.memo(function (_ref) {\n var children = _ref.children;\n return children;\n}, function (_, next) {\n return next.cache;\n});\nif (false) {}\n/* harmony default export */ const Popup_PopupContent = (PopupContent);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/Popup/index.js\n\n\n\n\n\n\n\n\n\n\n\n\nvar Popup = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var popup = props.popup,\n className = props.className,\n prefixCls = props.prefixCls,\n style = props.style,\n target = props.target,\n _onVisibleChanged = props.onVisibleChanged,\n open = props.open,\n keepDom = props.keepDom,\n onClick = props.onClick,\n mask = props.mask,\n arrow = props.arrow,\n arrowPos = props.arrowPos,\n align = props.align,\n motion = props.motion,\n maskMotion = props.maskMotion,\n forceRender = props.forceRender,\n getPopupContainer = props.getPopupContainer,\n autoDestroy = props.autoDestroy,\n Portal = props.portal,\n zIndex = props.zIndex,\n onMouseEnter = props.onMouseEnter,\n onMouseLeave = props.onMouseLeave,\n ready = props.ready,\n offsetX = props.offsetX,\n offsetY = props.offsetY,\n onAlign = props.onAlign,\n onPrepare = props.onPrepare,\n stretch = props.stretch,\n targetWidth = props.targetWidth,\n targetHeight = props.targetHeight;\n var childNode = typeof popup === \'function\' ? popup() : popup;\n\n // We can not remove holder only when motion finished.\n var isNodeVisible = open || keepDom;\n\n // ======================= Container ========================\n var getPopupContainerNeedParams = (getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.length) > 0;\n var _React$useState = react.useState(!getPopupContainer || !getPopupContainerNeedParams),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n show = _React$useState2[0],\n setShow = _React$useState2[1];\n\n // Delay to show since `getPopupContainer` need target element\n hooks_useLayoutEffect(function () {\n if (!show && getPopupContainerNeedParams && target) {\n setShow(true);\n }\n }, [show, getPopupContainerNeedParams, target]);\n\n // ========================= Render =========================\n if (!show) {\n return null;\n }\n\n // >>>>> Offset\n var offsetStyle = ready || !open ? {\n left: offsetX,\n top: offsetY\n } : {\n left: \'-1000vw\',\n top: \'-1000vh\'\n };\n\n // >>>>> Misc\n var miscStyle = {};\n if (stretch) {\n if (stretch.includes(\'height\') && targetHeight) {\n miscStyle.height = targetHeight;\n } else if (stretch.includes(\'minHeight\') && targetHeight) {\n miscStyle.minHeight = targetHeight;\n }\n if (stretch.includes(\'width\') && targetWidth) {\n miscStyle.width = targetWidth;\n } else if (stretch.includes(\'minWidth\') && targetWidth) {\n miscStyle.minWidth = targetWidth;\n }\n }\n if (!open) {\n miscStyle.pointerEvents = \'none\';\n }\n return /*#__PURE__*/react.createElement(Portal, {\n open: forceRender || isNodeVisible,\n getContainer: getPopupContainer && function () {\n return getPopupContainer(target);\n },\n autoDestroy: autoDestroy\n }, /*#__PURE__*/react.createElement(Mask, {\n prefixCls: prefixCls,\n open: open,\n zIndex: zIndex,\n mask: mask,\n motion: maskMotion\n }), /*#__PURE__*/react.createElement(rc_resize_observer_es, {\n onResize: onAlign,\n disabled: !open\n }, function (resizeObserverRef) {\n return /*#__PURE__*/react.createElement(rc_motion_es, extends_extends({\n motionAppear: true,\n motionEnter: true,\n motionLeave: true,\n removeOnLeave: false,\n forceRender: forceRender,\n leavedClassName: "".concat(prefixCls, "-hidden")\n }, motion, {\n onAppearPrepare: onPrepare,\n onEnterPrepare: onPrepare,\n visible: open,\n onVisibleChanged: function onVisibleChanged(nextVisible) {\n var _motion$onVisibleChan;\n motion === null || motion === void 0 ? void 0 : (_motion$onVisibleChan = motion.onVisibleChanged) === null || _motion$onVisibleChan === void 0 ? void 0 : _motion$onVisibleChan.call(motion, nextVisible);\n _onVisibleChanged(nextVisible);\n }\n }), function (_ref, motionRef) {\n var motionClassName = _ref.className,\n motionStyle = _ref.style;\n var cls = classnames_default()(prefixCls, motionClassName, className);\n return /*#__PURE__*/react.createElement("div", {\n ref: composeRef(resizeObserverRef, ref, motionRef),\n className: cls,\n style: _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({\n \'--arrow-x\': "".concat(arrowPos.x || 0, "px"),\n \'--arrow-y\': "".concat(arrowPos.y || 0, "px")\n }, offsetStyle), miscStyle), motionStyle), {}, {\n boxSizing: \'border-box\',\n zIndex: zIndex\n }, style),\n onMouseEnter: onMouseEnter,\n onMouseLeave: onMouseLeave,\n onClick: onClick\n }, arrow && /*#__PURE__*/react.createElement(Arrow, {\n prefixCls: prefixCls,\n arrow: arrow,\n arrowPos: arrowPos,\n align: align\n }), /*#__PURE__*/react.createElement(Popup_PopupContent, {\n cache: !open\n }, childNode));\n });\n }));\n});\nif (false) {}\n/* harmony default export */ const es_Popup = (Popup);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/TriggerWrapper.js\n\n\nvar TriggerWrapper = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var children = props.children,\n getTriggerDOMNode = props.getTriggerDOMNode;\n var canUseRef = supportRef(children);\n\n // When use `getTriggerDOMNode`, we should do additional work to get the real dom\n var setRef = react.useCallback(function (node) {\n fillRef(ref, getTriggerDOMNode ? getTriggerDOMNode(node) : node);\n }, [getTriggerDOMNode]);\n var mergedRef = useComposeRef(setRef, children.ref);\n return canUseRef ? /*#__PURE__*/react.cloneElement(children, {\n ref: mergedRef\n }) : children;\n});\nif (false) {}\n/* harmony default export */ const es_TriggerWrapper = (TriggerWrapper);\n;// CONCATENATED MODULE: ./node_modules/@rc-component/trigger/es/index.js\n\n\n\nvar es_excluded = ["prefixCls", "children", "action", "showAction", "hideAction", "popupVisible", "defaultPopupVisible", "onPopupVisibleChange", "afterPopupVisibleChange", "mouseEnterDelay", "mouseLeaveDelay", "focusDelay", "blurDelay", "mask", "maskClosable", "getPopupContainer", "forceRender", "autoDestroy", "destroyPopupOnHide", "popup", "popupClassName", "popupStyle", "popupPlacement", "builtinPlacements", "popupAlign", "zIndex", "stretch", "getPopupClassNameFromAlign", "alignPoint", "onPopupClick", "onPopupAlign", "arrow", "popupMotion", "maskMotion", "popupTransitionName", "popupAnimation", "maskTransitionName", "maskAnimation", "className", "getTriggerDOMNode"];\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nfunction generateTrigger() {\n var PortalComponent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : portal_es;\n var Trigger = /*#__PURE__*/react.forwardRef(function (props, ref) {\n var _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-trigger-popup\' : _props$prefixCls,\n children = props.children,\n _props$action = props.action,\n action = _props$action === void 0 ? \'hover\' : _props$action,\n showAction = props.showAction,\n hideAction = props.hideAction,\n popupVisible = props.popupVisible,\n defaultPopupVisible = props.defaultPopupVisible,\n onPopupVisibleChange = props.onPopupVisibleChange,\n afterPopupVisibleChange = props.afterPopupVisibleChange,\n mouseEnterDelay = props.mouseEnterDelay,\n _props$mouseLeaveDela = props.mouseLeaveDelay,\n mouseLeaveDelay = _props$mouseLeaveDela === void 0 ? 0.1 : _props$mouseLeaveDela,\n focusDelay = props.focusDelay,\n blurDelay = props.blurDelay,\n mask = props.mask,\n _props$maskClosable = props.maskClosable,\n maskClosable = _props$maskClosable === void 0 ? true : _props$maskClosable,\n getPopupContainer = props.getPopupContainer,\n forceRender = props.forceRender,\n autoDestroy = props.autoDestroy,\n destroyPopupOnHide = props.destroyPopupOnHide,\n popup = props.popup,\n popupClassName = props.popupClassName,\n popupStyle = props.popupStyle,\n popupPlacement = props.popupPlacement,\n _props$builtinPlaceme = props.builtinPlacements,\n builtinPlacements = _props$builtinPlaceme === void 0 ? {} : _props$builtinPlaceme,\n popupAlign = props.popupAlign,\n zIndex = props.zIndex,\n stretch = props.stretch,\n getPopupClassNameFromAlign = props.getPopupClassNameFromAlign,\n alignPoint = props.alignPoint,\n onPopupClick = props.onPopupClick,\n onPopupAlign = props.onPopupAlign,\n arrow = props.arrow,\n popupMotion = props.popupMotion,\n maskMotion = props.maskMotion,\n popupTransitionName = props.popupTransitionName,\n popupAnimation = props.popupAnimation,\n maskTransitionName = props.maskTransitionName,\n maskAnimation = props.maskAnimation,\n className = props.className,\n getTriggerDOMNode = props.getTriggerDOMNode,\n restProps = objectWithoutProperties_objectWithoutProperties(props, es_excluded);\n var mergedAutoDestroy = autoDestroy || destroyPopupOnHide || false;\n\n // =========================== Mobile ===========================\n var _React$useState = react.useState(false),\n _React$useState2 = slicedToArray_slicedToArray(_React$useState, 2),\n mobile = _React$useState2[0],\n setMobile = _React$useState2[1];\n hooks_useLayoutEffect(function () {\n setMobile(es_isMobile());\n }, []);\n\n // ========================== Context ===========================\n var subPopupElements = react.useRef({});\n var parentContext = react.useContext(trigger_es_context);\n var context = react.useMemo(function () {\n return {\n registerSubPopup: function registerSubPopup(id, subPopupEle) {\n subPopupElements.current[id] = subPopupEle;\n parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, subPopupEle);\n }\n };\n }, [parentContext]);\n\n // =========================== Popup ============================\n var id = useId();\n var _React$useState3 = react.useState(null),\n _React$useState4 = slicedToArray_slicedToArray(_React$useState3, 2),\n popupEle = _React$useState4[0],\n setPopupEle = _React$useState4[1];\n var setPopupRef = useEvent(function (node) {\n if (isDOM(node) && popupEle !== node) {\n setPopupEle(node);\n }\n parentContext === null || parentContext === void 0 ? void 0 : parentContext.registerSubPopup(id, node);\n });\n\n // =========================== Target ===========================\n // Use state to control here since `useRef` update not trigger render\n var _React$useState5 = react.useState(null),\n _React$useState6 = slicedToArray_slicedToArray(_React$useState5, 2),\n targetEle = _React$useState6[0],\n setTargetEle = _React$useState6[1];\n var setTargetRef = useEvent(function (node) {\n if (isDOM(node) && targetEle !== node) {\n setTargetEle(node);\n }\n });\n\n // ========================== Children ==========================\n var child = react.Children.only(children);\n var originChildProps = (child === null || child === void 0 ? void 0 : child.props) || {};\n var cloneProps = {};\n var inPopupOrChild = useEvent(function (ele) {\n var _childDOM$getRootNode, _popupEle$getRootNode;\n var childDOM = targetEle;\n return (childDOM === null || childDOM === void 0 ? void 0 : childDOM.contains(ele)) || (childDOM === null || childDOM === void 0 ? void 0 : (_childDOM$getRootNode = childDOM.getRootNode()) === null || _childDOM$getRootNode === void 0 ? void 0 : _childDOM$getRootNode.host) === ele || ele === childDOM || (popupEle === null || popupEle === void 0 ? void 0 : popupEle.contains(ele)) || (popupEle === null || popupEle === void 0 ? void 0 : (_popupEle$getRootNode = popupEle.getRootNode()) === null || _popupEle$getRootNode === void 0 ? void 0 : _popupEle$getRootNode.host) === ele || ele === popupEle || Object.values(subPopupElements.current).some(function (subPopupEle) {\n return (subPopupEle === null || subPopupEle === void 0 ? void 0 : subPopupEle.contains(ele)) || ele === subPopupEle;\n });\n });\n\n // =========================== Motion ===========================\n var mergePopupMotion = getMotion(prefixCls, popupMotion, popupAnimation, popupTransitionName);\n var mergeMaskMotion = getMotion(prefixCls, maskMotion, maskAnimation, maskTransitionName);\n\n // ============================ Open ============================\n var _React$useState7 = react.useState(defaultPopupVisible || false),\n _React$useState8 = slicedToArray_slicedToArray(_React$useState7, 2),\n internalOpen = _React$useState8[0],\n setInternalOpen = _React$useState8[1];\n\n // Render still use props as first priority\n var mergedOpen = popupVisible !== null && popupVisible !== void 0 ? popupVisible : internalOpen;\n\n // We use effect sync here in case `popupVisible` back to `undefined`\n var setMergedOpen = useEvent(function (nextOpen) {\n if (popupVisible === undefined) {\n setInternalOpen(nextOpen);\n }\n });\n hooks_useLayoutEffect(function () {\n setInternalOpen(popupVisible || false);\n }, [popupVisible]);\n var openRef = react.useRef(mergedOpen);\n openRef.current = mergedOpen;\n var internalTriggerOpen = useEvent(function (nextOpen) {\n if (mergedOpen !== nextOpen) {\n setMergedOpen(nextOpen);\n onPopupVisibleChange === null || onPopupVisibleChange === void 0 ? void 0 : onPopupVisibleChange(nextOpen);\n }\n });\n\n // Trigger for delay\n var delayRef = react.useRef();\n var clearDelay = function clearDelay() {\n clearTimeout(delayRef.current);\n };\n var triggerOpen = function triggerOpen(nextOpen) {\n var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n clearDelay();\n if (delay === 0) {\n internalTriggerOpen(nextOpen);\n } else {\n delayRef.current = setTimeout(function () {\n internalTriggerOpen(nextOpen);\n }, delay * 1000);\n }\n };\n react.useEffect(function () {\n return clearDelay;\n }, []);\n\n // ========================== Motion ============================\n var _React$useState9 = react.useState(false),\n _React$useState10 = slicedToArray_slicedToArray(_React$useState9, 2),\n inMotion = _React$useState10[0],\n setInMotion = _React$useState10[1];\n var mountRef = react.useRef(true);\n hooks_useLayoutEffect(function () {\n if (!mountRef.current || mergedOpen) {\n setInMotion(true);\n }\n mountRef.current = true;\n }, [mergedOpen]);\n var _React$useState11 = react.useState(null),\n _React$useState12 = slicedToArray_slicedToArray(_React$useState11, 2),\n motionPrepareResolve = _React$useState12[0],\n setMotionPrepareResolve = _React$useState12[1];\n\n // =========================== Align ============================\n var _React$useState13 = react.useState([0, 0]),\n _React$useState14 = slicedToArray_slicedToArray(_React$useState13, 2),\n mousePos = _React$useState14[0],\n setMousePos = _React$useState14[1];\n var setMousePosByEvent = function setMousePosByEvent(event) {\n setMousePos([event.clientX, event.clientY]);\n };\n var _useAlign = useAlign(mergedOpen, popupEle, alignPoint ? mousePos : targetEle, popupPlacement, builtinPlacements, popupAlign, onPopupAlign),\n _useAlign2 = slicedToArray_slicedToArray(_useAlign, 9),\n ready = _useAlign2[0],\n offsetX = _useAlign2[1],\n offsetY = _useAlign2[2],\n arrowX = _useAlign2[3],\n arrowY = _useAlign2[4],\n scaleX = _useAlign2[5],\n scaleY = _useAlign2[6],\n alignInfo = _useAlign2[7],\n onAlign = _useAlign2[8];\n var triggerAlign = useEvent(function () {\n if (!inMotion) {\n onAlign();\n }\n });\n useWatch(mergedOpen, targetEle, popupEle, triggerAlign);\n hooks_useLayoutEffect(function () {\n triggerAlign();\n }, [mousePos]);\n\n // When no builtinPlacements and popupAlign changed\n hooks_useLayoutEffect(function () {\n if (mergedOpen && !(builtinPlacements !== null && builtinPlacements !== void 0 && builtinPlacements[popupPlacement])) {\n triggerAlign();\n }\n }, [JSON.stringify(popupAlign)]);\n var alignedClassName = react.useMemo(function () {\n var baseClassName = getAlignPopupClassName(builtinPlacements, prefixCls, alignInfo, alignPoint);\n return classnames_default()(baseClassName, getPopupClassNameFromAlign === null || getPopupClassNameFromAlign === void 0 ? void 0 : getPopupClassNameFromAlign(alignInfo));\n }, [alignInfo, getPopupClassNameFromAlign, builtinPlacements, prefixCls, alignPoint]);\n react.useImperativeHandle(ref, function () {\n return {\n forceAlign: triggerAlign\n };\n });\n\n // ========================== Motion ============================\n var onVisibleChanged = function onVisibleChanged(visible) {\n setInMotion(false);\n onAlign();\n afterPopupVisibleChange === null || afterPopupVisibleChange === void 0 ? void 0 : afterPopupVisibleChange(visible);\n };\n\n // We will trigger align when motion is in prepare\n var onPrepare = function onPrepare() {\n return new Promise(function (resolve) {\n setMotionPrepareResolve(function () {\n return resolve;\n });\n });\n };\n hooks_useLayoutEffect(function () {\n if (motionPrepareResolve) {\n onAlign();\n motionPrepareResolve();\n setMotionPrepareResolve(null);\n }\n }, [motionPrepareResolve]);\n\n // ========================== Stretch ===========================\n var _React$useState15 = react.useState(0),\n _React$useState16 = slicedToArray_slicedToArray(_React$useState15, 2),\n targetWidth = _React$useState16[0],\n setTargetWidth = _React$useState16[1];\n var _React$useState17 = react.useState(0),\n _React$useState18 = slicedToArray_slicedToArray(_React$useState17, 2),\n targetHeight = _React$useState18[0],\n setTargetHeight = _React$useState18[1];\n var onTargetResize = function onTargetResize(_, ele) {\n triggerAlign();\n if (stretch) {\n var rect = ele.getBoundingClientRect();\n setTargetWidth(rect.width);\n setTargetHeight(rect.height);\n }\n };\n\n // =========================== Action ===========================\n var _useAction = useAction(mobile, action, showAction, hideAction),\n _useAction2 = slicedToArray_slicedToArray(_useAction, 2),\n showActions = _useAction2[0],\n hideActions = _useAction2[1];\n\n // Util wrapper for trigger action\n var wrapperAction = function wrapperAction(eventName, nextOpen, delay, preEvent) {\n cloneProps[eventName] = function (event) {\n var _originChildProps$eve;\n preEvent === null || preEvent === void 0 ? void 0 : preEvent(event);\n triggerOpen(nextOpen, delay);\n\n // Pass to origin\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n (_originChildProps$eve = originChildProps[eventName]) === null || _originChildProps$eve === void 0 ? void 0 : _originChildProps$eve.call.apply(_originChildProps$eve, [originChildProps, event].concat(args));\n };\n };\n\n // ======================= Action: Click ========================\n var clickToShow = showActions.has(\'click\');\n var clickToHide = hideActions.has(\'click\') || hideActions.has(\'contextMenu\');\n if (clickToShow || clickToHide) {\n cloneProps.onClick = function (event) {\n var _originChildProps$onC;\n if (openRef.current && clickToHide) {\n triggerOpen(false);\n } else if (!openRef.current && clickToShow) {\n setMousePosByEvent(event);\n triggerOpen(true);\n }\n\n // Pass to origin\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n (_originChildProps$onC = originChildProps.onClick) === null || _originChildProps$onC === void 0 ? void 0 : _originChildProps$onC.call.apply(_originChildProps$onC, [originChildProps, event].concat(args));\n };\n }\n\n // Click to hide is special action since click popup element should not hide\n react.useEffect(function () {\n if (clickToHide && popupEle && (!mask || maskClosable)) {\n var clickInside = false;\n\n // User may mouseDown inside and drag out of popup and mouse up\n // Record here to prevent close\n var onWindowMouseDown = function onWindowMouseDown(_ref) {\n var target = _ref.target;\n clickInside = inPopupOrChild(target);\n };\n var onWindowClick = function onWindowClick(_ref2) {\n var target = _ref2.target;\n if (openRef.current && !clickInside && !inPopupOrChild(target)) {\n triggerOpen(false);\n }\n };\n var win = getWin(popupEle);\n var targetRoot = targetEle === null || targetEle === void 0 ? void 0 : targetEle.getRootNode();\n win.addEventListener(\'mousedown\', onWindowMouseDown);\n win.addEventListener(\'click\', onWindowClick);\n\n // shadow root\n var inShadow = targetRoot && targetRoot !== targetEle.ownerDocument;\n if (inShadow) {\n targetRoot.addEventListener(\'mousedown\', onWindowMouseDown);\n targetRoot.addEventListener(\'click\', onWindowClick);\n }\n\n // Warning if target and popup not in same root\n if (false) { var popupRoot; }\n return function () {\n win.removeEventListener(\'mousedown\', onWindowMouseDown);\n win.removeEventListener(\'click\', onWindowClick);\n if (inShadow) {\n targetRoot.removeEventListener(\'mousedown\', onWindowMouseDown);\n targetRoot.removeEventListener(\'click\', onWindowClick);\n }\n };\n }\n }, [clickToHide, targetEle, popupEle, mask, maskClosable]);\n\n // ======================= Action: Hover ========================\n var hoverToShow = showActions.has(\'hover\');\n var hoverToHide = hideActions.has(\'hover\');\n var onPopupMouseEnter;\n var onPopupMouseLeave;\n if (hoverToShow) {\n wrapperAction(\'onMouseEnter\', true, mouseEnterDelay, function (event) {\n setMousePosByEvent(event);\n });\n onPopupMouseEnter = function onPopupMouseEnter() {\n triggerOpen(true, mouseEnterDelay);\n };\n\n // Align Point\n if (alignPoint) {\n cloneProps.onMouseMove = function (event) {\n var _originChildProps$onM;\n // setMousePosByEvent(event);\n (_originChildProps$onM = originChildProps.onMouseMove) === null || _originChildProps$onM === void 0 ? void 0 : _originChildProps$onM.call(originChildProps, event);\n };\n }\n }\n if (hoverToHide) {\n wrapperAction(\'onMouseLeave\', false, mouseLeaveDelay);\n onPopupMouseLeave = function onPopupMouseLeave() {\n triggerOpen(false, mouseLeaveDelay);\n };\n }\n\n // ======================= Action: Focus ========================\n if (showActions.has(\'focus\')) {\n wrapperAction(\'onFocus\', true, focusDelay);\n }\n if (hideActions.has(\'focus\')) {\n wrapperAction(\'onBlur\', false, blurDelay);\n }\n\n // ==================== Action: ContextMenu =====================\n if (showActions.has(\'contextMenu\')) {\n cloneProps.onContextMenu = function (event) {\n var _originChildProps$onC2;\n setMousePosByEvent(event);\n triggerOpen(true);\n event.preventDefault();\n\n // Pass to origin\n for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {\n args[_key3 - 1] = arguments[_key3];\n }\n (_originChildProps$onC2 = originChildProps.onContextMenu) === null || _originChildProps$onC2 === void 0 ? void 0 : _originChildProps$onC2.call.apply(_originChildProps$onC2, [originChildProps, event].concat(args));\n };\n }\n\n // ========================= ClassName ==========================\n if (className) {\n cloneProps.className = classnames_default()(originChildProps.className, className);\n }\n\n // =========================== Render ===========================\n var mergedChildrenProps = _objectSpread2(_objectSpread2({}, originChildProps), cloneProps);\n\n // Pass props into cloneProps for nest usage\n var passedProps = {};\n var passedEventList = [\'onContextMenu\', \'onClick\', \'onMouseDown\', \'onTouchStart\', \'onMouseEnter\', \'onMouseLeave\', \'onFocus\', \'onBlur\'];\n passedEventList.forEach(function (eventName) {\n if (restProps[eventName]) {\n passedProps[eventName] = function () {\n var _mergedChildrenProps$;\n for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {\n args[_key4] = arguments[_key4];\n }\n (_mergedChildrenProps$ = mergedChildrenProps[eventName]) === null || _mergedChildrenProps$ === void 0 ? void 0 : _mergedChildrenProps$.call.apply(_mergedChildrenProps$, [mergedChildrenProps].concat(args));\n restProps[eventName].apply(restProps, args);\n };\n }\n });\n\n // Child Node\n var triggerNode = /*#__PURE__*/react.cloneElement(child, _objectSpread2(_objectSpread2({}, mergedChildrenProps), passedProps));\n var arrowPos = {\n x: arrowX,\n y: arrowY\n };\n var innerArrow = arrow ? _objectSpread2({}, arrow !== true ? arrow : {}) : null;\n\n // Render\n return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(rc_resize_observer_es, {\n disabled: !mergedOpen,\n ref: setTargetRef,\n onResize: onTargetResize\n }, /*#__PURE__*/react.createElement(es_TriggerWrapper, {\n getTriggerDOMNode: getTriggerDOMNode\n }, triggerNode)), /*#__PURE__*/react.createElement(trigger_es_context.Provider, {\n value: context\n }, /*#__PURE__*/react.createElement(es_Popup, {\n portal: PortalComponent,\n ref: setPopupRef,\n prefixCls: prefixCls,\n popup: popup,\n className: classnames_default()(popupClassName, alignedClassName),\n style: popupStyle,\n target: targetEle,\n onMouseEnter: onPopupMouseEnter,\n onMouseLeave: onPopupMouseLeave,\n zIndex: zIndex\n // Open\n ,\n open: mergedOpen,\n keepDom: inMotion\n // Click\n ,\n onClick: onPopupClick\n // Mask\n ,\n mask: mask\n // Motion\n ,\n motion: mergePopupMotion,\n maskMotion: mergeMaskMotion,\n onVisibleChanged: onVisibleChanged,\n onPrepare: onPrepare\n // Portal\n ,\n forceRender: forceRender,\n autoDestroy: mergedAutoDestroy,\n getPopupContainer: getPopupContainer\n // Arrow\n ,\n align: alignInfo,\n arrow: innerArrow,\n arrowPos: arrowPos\n // Align\n ,\n ready: ready,\n offsetX: offsetX,\n offsetY: offsetY,\n onAlign: triggerAlign\n // Stretch\n ,\n stretch: stretch,\n targetWidth: targetWidth / scaleX,\n targetHeight: targetHeight / scaleY\n })));\n });\n if (false) {}\n return Trigger;\n}\n/* harmony default export */ const trigger_es = (generateTrigger(portal_es));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/placements.js\nvar autoAdjustOverflowTopBottom = {\n shiftX: 64,\n adjustY: 1\n};\nvar autoAdjustOverflowLeftRight = {\n adjustX: 1,\n shiftY: true\n};\nvar targetOffset = [0, 0];\nvar placements = {\n left: {\n points: [\'cr\', \'cl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n },\n right: {\n points: [\'cl\', \'cr\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n top: {\n points: [\'bc\', \'tc\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n bottom: {\n points: [\'tc\', \'bc\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n topLeft: {\n points: [\'bl\', \'tl\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n leftTop: {\n points: [\'tr\', \'tl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n },\n topRight: {\n points: [\'br\', \'tr\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, -4],\n targetOffset: targetOffset\n },\n rightTop: {\n points: [\'tl\', \'tr\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n bottomRight: {\n points: [\'tr\', \'br\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n rightBottom: {\n points: [\'bl\', \'br\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [4, 0],\n targetOffset: targetOffset\n },\n bottomLeft: {\n points: [\'tl\', \'bl\'],\n overflow: autoAdjustOverflowTopBottom,\n offset: [0, 4],\n targetOffset: targetOffset\n },\n leftBottom: {\n points: [\'br\', \'bl\'],\n overflow: autoAdjustOverflowLeftRight,\n offset: [-4, 0],\n targetOffset: targetOffset\n }\n};\n/* harmony default export */ const es_placements = ((/* unused pure expression or super */ null && (placements)));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/Popup.js\n\n\nfunction Popup_Popup(props) {\n var children = props.children,\n prefixCls = props.prefixCls,\n id = props.id,\n overlayInnerStyle = props.overlayInnerStyle,\n className = props.className,\n style = props.style;\n return /*#__PURE__*/react.createElement("div", {\n className: classnames_default()("".concat(prefixCls, "-content"), className),\n style: style\n }, /*#__PURE__*/react.createElement("div", {\n className: "".concat(prefixCls, "-inner"),\n id: id,\n role: "tooltip",\n style: overlayInnerStyle\n }, typeof children === \'function\' ? children() : children));\n}\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/Tooltip.js\n\n\n\nvar Tooltip_excluded = ["overlayClassName", "trigger", "mouseEnterDelay", "mouseLeaveDelay", "overlayStyle", "prefixCls", "children", "onVisibleChange", "afterVisibleChange", "transitionName", "animation", "motion", "placement", "align", "destroyTooltipOnHide", "defaultVisible", "getTooltipContainer", "overlayInnerStyle", "arrowContent", "overlay", "id", "showArrow"];\n\n\n\n\n\nvar Tooltip = function Tooltip(props, ref) {\n var overlayClassName = props.overlayClassName,\n _props$trigger = props.trigger,\n trigger = _props$trigger === void 0 ? [\'hover\'] : _props$trigger,\n _props$mouseEnterDela = props.mouseEnterDelay,\n mouseEnterDelay = _props$mouseEnterDela === void 0 ? 0 : _props$mouseEnterDela,\n _props$mouseLeaveDela = props.mouseLeaveDelay,\n mouseLeaveDelay = _props$mouseLeaveDela === void 0 ? 0.1 : _props$mouseLeaveDela,\n overlayStyle = props.overlayStyle,\n _props$prefixCls = props.prefixCls,\n prefixCls = _props$prefixCls === void 0 ? \'rc-tooltip\' : _props$prefixCls,\n children = props.children,\n onVisibleChange = props.onVisibleChange,\n afterVisibleChange = props.afterVisibleChange,\n transitionName = props.transitionName,\n animation = props.animation,\n motion = props.motion,\n _props$placement = props.placement,\n placement = _props$placement === void 0 ? \'right\' : _props$placement,\n _props$align = props.align,\n align = _props$align === void 0 ? {} : _props$align,\n _props$destroyTooltip = props.destroyTooltipOnHide,\n destroyTooltipOnHide = _props$destroyTooltip === void 0 ? false : _props$destroyTooltip,\n defaultVisible = props.defaultVisible,\n getTooltipContainer = props.getTooltipContainer,\n overlayInnerStyle = props.overlayInnerStyle,\n arrowContent = props.arrowContent,\n overlay = props.overlay,\n id = props.id,\n _props$showArrow = props.showArrow,\n showArrow = _props$showArrow === void 0 ? true : _props$showArrow,\n restProps = objectWithoutProperties_objectWithoutProperties(props, Tooltip_excluded);\n var triggerRef = (0,react.useRef)(null);\n (0,react.useImperativeHandle)(ref, function () {\n return triggerRef.current;\n });\n var extraProps = _objectSpread2({}, restProps);\n if (\'visible\' in props) {\n extraProps.popupVisible = props.visible;\n }\n var getPopupElement = function getPopupElement() {\n return /*#__PURE__*/react.createElement(Popup_Popup, {\n key: "content",\n prefixCls: prefixCls,\n id: id,\n overlayInnerStyle: overlayInnerStyle\n }, overlay);\n };\n return /*#__PURE__*/react.createElement(trigger_es, extends_extends({\n popupClassName: overlayClassName,\n prefixCls: prefixCls,\n popup: getPopupElement,\n action: trigger,\n builtinPlacements: placements,\n popupPlacement: placement,\n ref: triggerRef,\n popupAlign: align,\n getPopupContainer: getTooltipContainer,\n onPopupVisibleChange: onVisibleChange,\n afterPopupVisibleChange: afterVisibleChange,\n popupTransitionName: transitionName,\n popupAnimation: animation,\n popupMotion: motion,\n defaultPopupVisible: defaultVisible,\n autoDestroy: destroyTooltipOnHide,\n mouseLeaveDelay: mouseLeaveDelay,\n popupStyle: overlayStyle,\n mouseEnterDelay: mouseEnterDelay,\n arrow: showArrow\n }, extraProps), children);\n};\n/* harmony default export */ const es_Tooltip = (/*#__PURE__*/(0,react.forwardRef)(Tooltip));\n;// CONCATENATED MODULE: ./node_modules/rc-tooltip/es/index.js\n\n\n\n/* harmony default export */ const rc_tooltip_es = (es_Tooltip);\n;// CONCATENATED MODULE: ./src/ui/TooltipSlider.tsx\n/**\n * rc-tooltip tooltip slider\n */\nvar TooltipSlider_assign = (undefined && undefined.__assign) || function () {\n TooltipSlider_assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return TooltipSlider_assign.apply(this, arguments);\n};\nvar TooltipSlider_rest = (undefined && undefined.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n};\n\n\n\n\n\nvar HandleTooltip = function (props) {\n var value = props.value, children = props.children, visible = props.visible, _a = props.tipFormatter, tipFormatter = _a === void 0 ? function (val) { return "".concat(val, " %"); } : _a, restProps = TooltipSlider_rest(props, ["value", "children", "visible", "tipFormatter"]);\n var tooltipRef = react.useRef();\n var rafRef = react.useRef(null);\n function cancelKeepAlign() {\n raf/* default.cancel */.Z.cancel(rafRef.current);\n }\n function keepAlign() {\n rafRef.current = (0,raf/* default */.Z)(function () {\n // tooltipRef.current?.forcePopupAlign();\n });\n }\n react.useEffect(function () {\n if (visible) {\n keepAlign();\n }\n else {\n cancelKeepAlign();\n }\n return cancelKeepAlign;\n }, [value, visible]);\n return (react.createElement(rc_tooltip_es, TooltipSlider_assign({ placement: "top", overlay: tipFormatter(value), overlayInnerStyle: { minHeight: "auto" }, ref: tooltipRef, visible: visible }, restProps), children));\n};\nvar handleRender = function (node, props) {\n return (React.createElement(HandleTooltip, { value: props.value, visible: props.dragging }, node));\n};\nvar TooltipSlider = function (_a) {\n var tipFormatter = _a.tipFormatter, tipProps = _a.tipProps, props = TooltipSlider_rest(_a, ["tipFormatter", "tipProps"]);\n var tipHandleRender = function (node, handleProps) {\n return (react.createElement(HandleTooltip, TooltipSlider_assign({ value: handleProps.value, visible: handleProps.dragging, tipFormatter: tipFormatter }, tipProps), node));\n };\n return react.createElement(es, TooltipSlider_assign({}, props, { handleRender: tipHandleRender }));\n};\n/* harmony default export */ const ui_TooltipSlider = (TooltipSlider);\n\n// EXTERNAL MODULE: ./node_modules/css-loader/dist/cjs.js!./node_modules/rc-slider/assets/index.css\nvar assets = __webpack_require__(687);\n;// CONCATENATED MODULE: ./node_modules/rc-slider/assets/index.css\n\n \n \n \n \n \n \n \n \n \n\nvar assets_options = {};\n\nassets_options.styleTagTransform = (styleTagTransform_default());\nassets_options.setAttributes = (setAttributesWithoutAttributes_default());\n\n assets_options.insert = insertBySelector_default().bind(null, "head");\n \nassets_options.domAPI = (styleDomAPI_default());\nassets_options.insertStyleElement = (insertStyleElement_default());\n\nvar assets_update = injectStylesIntoStyleTag_default()(assets/* default */.Z, assets_options);\n\n\n\n\n /* harmony default export */ const rc_slider_assets = (assets/* default */.Z && assets/* default.locals */.Z.locals ? assets/* default.locals */.Z.locals : undefined);\n\n;// CONCATENATED MODULE: ./src/ui/Controls.jsx\n/**\n * Relabi controls\n * @module src/ui/Controls.jsx;\n */\n\n\n\n\n\n\nvar WAVE_SHAPE_NAMES = ["sine", "triangle", "saw", "reverse_saw", "square"];\nfunction Controls(_ref) {\n var relabi = _ref.relabi;\n /**\n * Handle updating a slider\n */\n var onChange = (0,react.useCallback)(function (type, index) {\n return function (value) {\n if (type === "bound") {\n relabi.bounds[index].level = value;\n }\n if (type === "shape") {\n relabi.waves[index].shape = WAVE_SHAPE_NAMES[value];\n }\n if (type === "frequency") {\n relabi.waves[index].frequency = Math.exp(value);\n }\n if (type === "weight") {\n relabi.waves[index].weight = value;\n }\n if (type === "settings") {\n relabi.settings[index] = index === "speed" ? Math.exp(value) : value;\n }\n };\n }, [relabi]);\n if (!relabi) {\n return null;\n }\n return /*#__PURE__*/react.createElement(ControlRow, null, /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Bounds"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.bounds.map(function (bound, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "bound_".concat(index),\n type: "bound",\n index: index,\n onChange: onChange,\n min: -1,\n max: 1,\n step: 0.01,\n tipFormatter: function tipFormatter(value) {\n return -value;\n },\n defaultValue: bound.level,\n color: bound.color,\n reverse: true\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Wave frequencies"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.waves.map(function (wave, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "frequency_".concat(index),\n type: "frequency",\n index: index,\n onChange: onChange,\n min: -2,\n max: 3,\n step: 0.001,\n defaultValue: Math.log(wave.frequency),\n tipFormatter: function tipFormatter(value) {\n return Math.exp(value).toFixed(1);\n },\n color: "#8a8"\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Wave shapes"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.waves.map(function (wave, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "shape_".concat(index),\n type: "shape",\n index: index,\n onChange: onChange,\n min: 0,\n max: WAVE_SHAPE_NAMES.length - 1,\n step: 1,\n defaultValue: WAVE_SHAPE_NAMES.indexOf(wave.shape),\n color: "#aa8",\n tipFormatter: function tipFormatter(value) {\n return WAVE_SHAPE_NAMES[value];\n }\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Wave weights"), /*#__PURE__*/react.createElement(SliderRow, null, relabi === null || relabi === void 0 ? void 0 : relabi.waves.map(function (wave, index) {\n return /*#__PURE__*/react.createElement(ControlSlider, {\n rel: "weight_".concat(index),\n type: "weight",\n index: index,\n onChange: onChange,\n min: 0,\n max: 2,\n step: 0.01,\n defaultValue: wave.weight,\n color: "#99b"\n });\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Speed"), /*#__PURE__*/react.createElement(SliderRow, null, /*#__PURE__*/react.createElement(ControlSlider, {\n type: "settings",\n index: "speed",\n onChange: onChange,\n min: -2,\n max: 3,\n step: 0.01,\n defaultValue: Math.log(relabi.settings.speed),\n tipFormatter: function tipFormatter(value) {\n return Math.exp(value).toFixed(1);\n },\n color: "#a88"\n }))), /*#__PURE__*/react.createElement(ControlBox, null, /*#__PURE__*/react.createElement(Label, null, "Chaos"), /*#__PURE__*/react.createElement(SliderRow, null, /*#__PURE__*/react.createElement(ControlSlider, {\n type: "settings",\n index: "feedback",\n onChange: onChange,\n min: 0,\n max: 0.5,\n step: 0.01,\n defaultValue: relabi.settings.feedback,\n color: "#a88"\n }))));\n}\n\n/**\n * UI Elements\n */\nvar ControlRow = function ControlRow(_ref2) {\n var children = _ref2.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n display: "flex",\n flexDirection: "row",\n marginTop: "1rem"\n }\n }, children);\n};\nvar ControlBox = function ControlBox(_ref3) {\n var children = _ref3.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n marginLeft: "1rem"\n }\n }, children);\n};\nvar SliderRow = function SliderRow(_ref4) {\n var children = _ref4.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n display: "flex",\n flexDireciton: "row",\n height: "10rem",\n marginTop: "0.5rem"\n }\n }, children);\n};\nvar Label = function Label(_ref5) {\n var children = _ref5.children;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n fontSize: "0.75rem"\n }\n }, children);\n};\nvar ControlSlider = function ControlSlider(_ref6) {\n var type = _ref6.type,\n index = _ref6.index,\n min = _ref6.min,\n max = _ref6.max,\n step = _ref6.step,\n reverse = _ref6.reverse,\n defaultValue = _ref6.defaultValue,\n color = _ref6.color,\n onChange = _ref6.onChange,\n tipFormatter = _ref6.tipFormatter;\n return /*#__PURE__*/react.createElement("div", {\n style: {\n marginRight: "0.5rem"\n }\n }, /*#__PURE__*/react.createElement(ui_TooltipSlider, {\n vertical: true,\n min: min,\n max: max,\n step: step,\n reverse: reverse,\n defaultValue: defaultValue,\n onChange: onChange(type, index),\n handleStyle: {\n backgroundColor: color,\n borderColor: color,\n opacity: 1\n },\n trackStyle: {\n backgroundColor: "#888",\n width: "2px"\n },\n railStyle: {\n backgroundColor: "#888",\n width: "2px"\n },\n tipFormatter: tipFormatter || function (value) {\n return value;\n }\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 settings: {\n speed: 1.0,\n feedback: 0.2\n },\n waves: [{\n shape: "sine",\n frequency: 0.75,\n weight: 1\n }, {\n shape: "sine",\n frequency: 1.0,\n weight: 1\n }, {\n shape: "sine",\n frequency: 1.617,\n weight: 1\n }, {\n shape: "sine",\n frequency: 3.141,\n weight: 1\n }],\n bounds: [{\n level: -0.25,\n color: "#f33",\n sounds: [{\n instrument: "Kick"\n }, {\n instrument: "Snare"\n }]\n }, {\n level: 0.25,\n color: "#f83",\n sounds: [{\n instrument: "Hat"\n }, {\n instrument: "Perc"\n }]\n }\n // {\n // level: -0.25,\n // color: "#3b8",\n // sounds: [\n // { instrument: Kalimba, frequency: 440 },\n // { instrument: Kalimba, frequency: (440 * 3) / 2 },\n // ],\n // },\n // {\n // level: 0.25,\n // color: "#36f",\n // sounds: [\n // { instrument: Kalimba, frequency: (440 * 6) / 5 },\n // { instrument: Kalimba, frequency: (440 * 6) / 7 },\n // ],\n // },\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 }), /*#__PURE__*/react.createElement(Controls, {\n relabi: relabi\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.style.fontFamily = "Helvetica, Arial";\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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QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTSxDQUFDLGNBQWM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCLFlBQVksWUFBTSxDQUFDLG1CQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5QjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQkFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEIsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixnQkFBZ0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQVE7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLDZGQUE2RixzQkFBc0IsSUFBSSxxQkFBcUI7QUFDMUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLHNHQUFzRyxzQkFBc0IsSUFBSSx3QkFBd0I7QUFDdEs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixFQUFFO0FBQ3pCO0FBQ0E7QUFDQSxRQUFRLFlBQU0sMkdBQTJHLHNCQUFzQixJQUFJLHdCQUF3QjtBQUMzSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxvQkFBb0I7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFdBQVc7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Qzs7QUMxaEI4QjtBQUM5QjtBQUNrQztBQUNJO0FBQ047QUFDaEM7QUFDK0I7QUFDRztBQUNPO0FBQ1Q7QUFDVTtBQUNDO0FBQ0g7QUFDUDtBQUNMO0FBQ0E7QUFDQztBQUNRO0FBQ2hCO0FBQ1U7QUFDUztBQUNIO0FBQ0w7QUFDQztBQUM2RDtBQUMzQjtBQUNuRTtBQUNxQztBQUNyQjtBQUNoQjtBQUNzQztBQUNyQjtBQUNqQixpQzs7QUNoQytDO0FBQ2tCO0FBQ0Q7QUFDWDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxhQUFNLFNBQVMsMkJBQWE7QUFDekM7QUFDQSxjQUFjLDZCQUFvQixDQUFDLGFBQU07QUFDekM7QUFDQSx3QkFBd0IsNkJBQW9CLENBQUMsYUFBTTtBQUNuRCx1Q0FBdUMsU0FBSTtBQUMzQztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDOztBQ2pFd0Q7QUFDQTtBQUNnQjtBQUMxQztBQUNpQztBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTywwQkFBMEIsMkJBQWE7QUFDOUM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBLHlCQUF5QixhQUFNLEdBQUcsdUJBQXVCO0FBQ3pELDBCQUEwQixTQUFJLEdBQUcsdUJBQXVCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw2QkFBb0I7QUFDNUMsUUFBUSwyQkFBYTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qix1Q0FBeUI7QUFDdEQ7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsMkJBQWE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsNENBQTRDLFNBQVM7QUFDckQsQ0FBQztBQUNELGNBQWM7QUFDZDtBQUNBLENBQUM7QUFDRCx1Qzs7QUN4R3NDO0FBQ1A7QUFDL0I7QUFDQTtBQUNBO0FBQ08sNEJBQTRCLElBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVEsR0FBRyxZQUFZO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUM7O0FDeEN5QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixjQUFJO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEM7O0FDcEQyQztBQUNPO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ08sbUNBQW1DLGNBQWM7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsZ0JBQVU7QUFDdEMsNkJBQTZCLGdCQUFVO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCLEVBQUUsMEJBQTBCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRkFBbUYsZ0JBQVU7QUFDN0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRkFBa0YsZ0JBQVU7QUFDNUY7QUFDQSwrRUFBK0UsZ0JBQVU7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRDs7QUM5RmlEO0FBQ2E7QUFDbUI7QUFDMUM7QUFDc0I7QUFDbEI7QUFDZ0I7QUFDSDtBQUNkO0FBQ2E7QUFDSztBQUNoQjtBQUNXO0FBQ3ZCO0FBQ2tCO0FBQ1k7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNPLHdCQUF3QiwrQkFBZTtBQUM5QztBQUNBLGNBQWMsNkJBQW9CO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUJBQXlCLGFBQWE7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFFBQVE7QUFDckM7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLGdCQUFnQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQjtBQUM1QztBQUNBO0FBQ0EsMEJBQTBCLFdBQUs7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQSw0Q0FBNEM7QUFDNUM7QUFDQTtBQUNBLDZCQUE2QiwyQ0FBMkI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixnQkFBVTtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSwwQkFBMEIsY0FBYztBQUN4QztBQUNBLHNCQUFzQixnQ0FBa0I7QUFDeEMsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSwwQkFBMEIsb0JBQW9CO0FBQzlDO0FBQ0EsMEJBQTBCLFNBQVM7QUFDbkMsMEJBQTBCLFNBQVM7QUFDbkMsc0JBQXNCLGdDQUFrQjtBQUN4QyxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixjQUFjO0FBQ3hDO0FBQ0E7QUFDQSxzQkFBc0IsZ0NBQWtCO0FBQ3hDLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsZ0JBQVU7QUFDbkM7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQVU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFNBQUk7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFE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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFRO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFR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Qyx1QkFBdUI7QUFDeEQsc0NBQXNDLHVCQUF1QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0I7O0FDeE9zQztBQUN0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QUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Qzs7QUMxT3dCO0FBQ0k7QUFDWTtBQUNFO0FBQ0E7QUFDRztBQUNGO0FBQ0E7QUFDQztBQUNJO0FBQ2Y7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QUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDck1tQztBQUNxQjtBQUNnQjtBQUN0QjtBQUNSO0FBQ1Y7QUFDMEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELGdCQUFnQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBGQUEwRixRQUFRO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNVN3QztBQUMwQjtBQUNMO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLCtEQUFlO0FBQ3pDO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQSw2Q0FBNkMsU0FBSTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNuS2dEO0FBQ2dCO0FBQ1M7QUFDZDtBQUNvQjtBQUN2QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sb0NBQW9DO0FBQzlDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLHlEQUFTO0FBQ25DO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qiw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFJO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ2haNEM7QUFDRjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxVQUFVLGlDQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDcEs4QjtBQUN3QjtBQUNPO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxzQkFBc0Isb0RBQUk7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xFZ0Q7QUFDNkI7QUFDbEI7QUFDN0I7QUFDVTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLHlEQUFTO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUN0UHVCO0FBQ0E7QUFDRztBQUNDO0FBQ0M7QUFDNUIsaUM7O0FDTCtDO0FBQzJCO0FBQ1Y7QUFDWDtBQUNFO0FBQ1Y7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLGlEQUFpRCxtQkFBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDaExrQztBQUMrQjtBQUNsQjtBQUNBO0FBQ2E7QUFDSTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLHVCQUF1Qiw2REFBYTtBQUMzQztB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWUsT0FBTyxFOztBQ3poQlM7QUFDL0IsaUNBQWlDLG1CQUFtQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELGlEQUFlLGFBQWEsRTs7QUNYckI7QUFDUDtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBLEM7O0FDN0IwRDtBQUNXO0FBQ0c7QUFDa0I7QUFDMUY7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RUE7QUFDQTtBQUNBLGdCQUFnQiwyQkFBYztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsY0FBYSxHQUFHOztBQUUxQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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U0FBUyxDQUFDO0VBQ2xDaUosSUFBSSxDQUFDMEcsTUFBTSxlQUFDdEQsbUJBQUEsQ0FBQzBDLEdBQUcsTUFBRSxDQUFDLENBQUM7QUFDdEIsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3ZlcnNpb24uanM/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/ZGM5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL291dHB1dC5qcz8zZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvc2FtcGxlci5qcz81OTZiIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvaW5zdHJ1bWVudHMuanM/ZjlhMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvcmVsYWJpL2luZGV4LmpzPzAyZmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZi5qcz9mOGRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b1ByaW1pdGl2ZS5qcz85NzZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b1Byb3BlcnR5S2V5LmpzP2EyZmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5LmpzP2Q3MWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2FycmF5TGlrZVRvQXJyYXkuanM/MjIyZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vYXJyYXlXaXRob3V0SG9sZXMuanM/YzQ3ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaXRlcmFibGVUb0FycmF5LmpzP2QxYjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5LmpzPzZjMjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL25vbkl0ZXJhYmxlU3ByZWFkLmpzPzBhZDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5LmpzP2Y3YTMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2FycmF5V2l0aEhvbGVzLmpzPzJiZTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2l0ZXJhYmxlVG9BcnJheUxpbWl0LmpzPzgyZGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL25vbkl0ZXJhYmxlUmVzdC5qcz80ZWJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5LmpzP2ZjZDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvd2FybmluZy5qcz8yYjA2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2lzRXF1YWwuanM/NTlmYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VFdmVudC5qcz85ODEwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0RvbS9jYW5Vc2VEb20uanM/MzBkOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VMYXlvdXRFZmZlY3QuanM/NGNkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VTdGF0ZS5qcz83NjZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL2hvb2tzL3VzZU1lcmdlZFN0YXRlLmpzP2U5YzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHMuanM/MzMxNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZS5qcz9kMjE0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllcy5qcz85NDI5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyLmpzP2JiNzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvS2V5Q29kZS5qcz9lMDg5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvY29udGV4dC5qcz85M2Q3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvdXRpbC5qcz85ZWY5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvSGFuZGxlcy9IYW5kbGUuanM/OTlkZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL0hhbmRsZXMvaW5kZXguanM/YjAxOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL2hvb2tzL3VzZURyYWcuanM/MWYzZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL1RyYWNrcy9UcmFjay5qcz8zNDg0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvVHJhY2tzL2luZGV4LmpzP2JmZTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9NYXJrcy9NYXJrLmpzP2M0YjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9NYXJrcy9pbmRleC5qcz84YzUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvU3RlcHMvRG90LmpzPzQ1NDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9TdGVwcy9pbmRleC5qcz9jODU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvZXMvaG9va3MvdXNlT2Zmc2V0LmpzP2QyZTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9lcy9TbGlkZXIuanM/M2IzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2VzL2luZGV4LmpzP2IyMjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvYXNzZXRzL2Jvb3RzdHJhcC5jc3M/MGM4OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9ob29rcy91c2VNZW1vLmpzPzYyYmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvcmVmLmpzPzczZTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL0NvbnRleHQuanM/ZDgxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvdXNlRG9tLmpzP2Y4YjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvRG9tL2NvbnRhaW5zLmpzPzk3ODYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvRG9tL2R5bmFtaWNDU1MuanM/MDU0ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9nZXRTY3JvbGxCYXJTaXplLmpzP2FiMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL3V0aWwuanM/OTQ5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvdXNlU2Nyb2xsTG9ja2VyLmpzP2E4NzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL21vY2suanM/NDk2MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC9wb3J0YWwvZXMvUG9ydGFsLmpzPzU1YzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvcG9ydGFsL2VzL2luZGV4LmpzPzZkM2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvQ2hpbGRyZW4vdG9BcnJheS5qcz82NjZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy11dGlsL2VzL0RvbS9maW5kRE9NTm9kZS5qcz85YmU2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yZXNpemUtb2JzZXJ2ZXItcG9seWZpbGwvZGlzdC9SZXNpemVPYnNlcnZlci5lcy5qcz82ZGQ4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1yZXNpemUtb2JzZXJ2ZXIvZXMvdXRpbHMvb2JzZXJ2ZXJVdGlsLmpzPzQ3MTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrLmpzPzY5NTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzLmpzPzkyOTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NldFByb3RvdHlwZU9mLmpzPzQzNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2luaGVyaXRzLmpzPzk4YTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2dldFByb3RvdHlwZU9mLmpzPzMxNjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdC5qcz9kZGNiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQuanM/NDJjYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vcG9zc2libGVDb25zdHJ1Y3RvclJldHVybi5qcz8wZDQ3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVTdXBlci5qcz8zZDkxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1yZXNpemUtb2JzZXJ2ZXIvZXMvU2luZ2xlT2JzZXJ2ZXIvRG9tV3JhcHBlci5qcz84MTcxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1yZXNpemUtb2JzZXJ2ZXIvZXMvQ29sbGVjdGlvbi5qcz9jZjNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1yZXNpemUtb2JzZXJ2ZXIvZXMvU2luZ2xlT2JzZXJ2ZXIvaW5kZXguanM/NTJlNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtcmVzaXplLW9ic2VydmVyL2VzL2luZGV4LmpzP2I3NmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvaG9va3MvdXNlSWQuanM/NTc2MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9pc01vYmlsZS5qcz9lNTlmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvY29udGV4dC5qcz9jNTUzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvaG9va3MvdXNlQWN0aW9uLmpzP2EwNjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLXV0aWwvZXMvRG9tL2lzVmlzaWJsZS5qcz9jN2ZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvdXRpbC5qcz8xMjMzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvaG9va3MvdXNlQWxpZ24uanM/OTQ0YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL2hvb2tzL3VzZVdhdGNoLmpzP2EzMGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9jb250ZXh0LmpzPzg4YTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9Eb21XcmFwcGVyLmpzPzhiZmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9pbnRlcmZhY2UuanM/NGQyMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL3V0aWwvbW90aW9uLmpzPzhmYTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9ob29rcy91c2VEb21Nb3Rpb25FdmVudHMuanM/ZWZlMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2hvb2tzL3VzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3QuanM/ZmJkZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9lcy9yYWYuanM/YzIwMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL2hvb2tzL3VzZU5leHRGcmFtZS5qcz8wOTE1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvaG9va3MvdXNlU3RlcFF1ZXVlLmpzPzE1NWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9ob29rcy91c2VTdGF0dXMuanM/ZWVhYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtbW90aW9uL2VzL0NTU01vdGlvbi5qcz83YjIzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1tb3Rpb24vZXMvdXRpbC9kaWZmLmpzPzRiMzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9DU1NNb3Rpb25MaXN0LmpzPzljYTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JjLW1vdGlvbi9lcy9pbmRleC5qcz9mMTc0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvUG9wdXAvQXJyb3cuanM/N2MzZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL1BvcHVwL01hc2suanM/MTA1MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL1BvcHVwL1BvcHVwQ29udGVudC5qcz81MGFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AcmMtY29tcG9uZW50L3RyaWdnZXIvZXMvUG9wdXAvaW5kZXguanM/ODBjMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQHJjLWNvbXBvbmVudC90cmlnZ2VyL2VzL1RyaWdnZXJXcmFwcGVyLmpzPzY0MGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0ByYy1jb21wb25lbnQvdHJpZ2dlci9lcy9pbmRleC5qcz9iZjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy10b29sdGlwL2VzL3BsYWNlbWVudHMuanM/ZWUyYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9lcy9Qb3B1cC5qcz81YzA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy10b29sdGlwL2VzL1Rvb2x0aXAuanM/YzdkOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9lcy9pbmRleC5qcz8zOGIxIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy91aS9Ub29sdGlwU2xpZGVyLnRzeD8yYWQ0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yYy1zbGlkZXIvYXNzZXRzL2luZGV4LmNzcz9mZDFlIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy91aS9Db250cm9scy5qc3g/ZTkxMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvdWkvQXBwLmpzeD80NDJhIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9pbmRleC5qc3g/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/IC0xIDogMSk7XG5leHBvcnQgY29uc3QgcmFuZG51bGxzaWduID0gKCkgPT4ge1xuICB2YXIgciA9IHJhbmRvbSgpO1xuICByZXR1cm4gciA8IDAuMzMzID8gLTEgOiByIDwgMC42NjYgPyAwIDogMTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1ZXN0QXVkaW9Db250ZXh0KGZuKSB7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIGJ1dHRvbi5pbm5lckhUTUwgPSBcIlRhcCB0byBzdGFydCAtIHBsZWFzZSB1bm11dGUgeW91ciBkZXZpY2VcIjtcbiAgT2JqZWN0LmFzc2lnbihjb250YWluZXIuc3R5bGUsIHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgaGVpZ2h0OiBcIjEwMCVcIixcbiAgICB6SW5kZXg6IFwiMTAwMDBcIixcbiAgICB0b3A6IFwiMHB4XCIsXG4gICAgbGVmdDogXCIwcHhcIixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IFwicmdiYSgwLCAwLCAwLCAwLjgpXCIsXG4gIH0pO1xuICBPYmplY3QuYXNzaWduKGJ1dHRvbi5zdHlsZSwge1xuICAgIGRpc3BsYXk6IFwiYmxvY2tcIixcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIGxlZnQ6IFwiNTAlXCIsXG4gICAgdG9wOiBcIjUwJVwiLFxuICAgIHBhZGRpbmc6IFwiMjBweFwiLFxuICAgIGJhY2tncm91bmRDb2xvcjogXCIjN0YzM0VEXCIsXG4gICAgY29sb3I6IFwid2hpdGVcIixcbiAgICBmb250RmFtaWx5OiBcIidNZW5sbycsIG1vbm9zcGFjZVwiLFxuICAgIGJvcmRlclJhZGl1czogXCIzcHhcIixcbiAgICB0cmFuc2Zvcm06IFwidHJhbnNsYXRlM0QoLTUwJSwtNTAlLDApXCIsXG4gICAgdGV4dEFsaWduOiBcImNlbnRlclwiLFxuICAgIGxpbmVIZWlnaHQ6IFwiMS41XCIsXG4gICAgd2lkdGg6IFwiMTUwcHhcIixcbiAgICBjdXJzb3I6IFwicG9pbnRlclwiLFxuICB9KTtcbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGJ1dHRvbik7XG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgU3RhcnRBdWRpb0NvbnRleHQuc2V0Q29udGV4dChUb25lLmNvbnRleHQpO1xuICBTdGFydEF1ZGlvQ29udGV4dC5vbihidXR0b24pO1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQoKF8pID0+IHtcbiAgICBjb250YWluZXIucmVtb3ZlKCk7XG4gICAgZm4oKTtcbiAgfSk7XG59XG4iLCIvKipcbiAqIFJlbGFiaSB3YXZlZm9ybSBkaXNwbGF5XG4gKiBAbW9kdWxlIHNyYy9yZWxhYmkvY2FudmFzLmpzO1xuICovXG5cbmNvbnN0IE5PVEVfUkFESVVTID0gNztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVsYWJpQ2FudmFzIHtcbiAgLyoqXG4gICAqIEluaXRpYWxpemUgcmVsYWJpIHdhdmUgcmVuZGVyZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yKHsgcmVsYWJpLCBwYXJlbnQgfSkge1xuICAgIHRoaXMucmVsYWJpID0gcmVsYWJpO1xuICAgIHRoaXMuaGVpZ2h0ID0gNDAwO1xuICAgIHRoaXMubGFzdEZyYW1lID0gMDtcbiAgICB0aGlzLmxhc3RBcHBlbmRUaW1lID0gMDtcbiAgICB0aGlzLmxhc3RBcHBlbmRGcmFtZSA9IDA7XG5cbiAgICAvLyBTcGVlZCBvZiB0aGUgd2F2ZSBpbiBwaXhlbHMgcGVyIHNlY29uZFxuICAgIHRoaXMuc3BlZWQgPSAxIC8gNTtcblxuICAgIC8vIFBvc2l0aW9uIG9mIGN1cnJlbnQgdGltZSBvbiB0aGUgc2NyZWVuLCBmcm9tIHRoZSBsZWZ0XG4gICAgdGhpcy50WmVyb09mZnNldCA9IDIwO1xuXG4gICAgLy8gQXR0YWNoIHRvIHRoZSBET01cbiAgICB0aGlzLmFwcGVuZENhbnZhcyhwYXJlbnQpO1xuICAgIC8vIEluaXRpYWxpemUgYXJyYXlcbiAgICB0aGlzLnZhbHVlcyA9IG5ldyBBcnJheSh3aW5kb3cuaW5uZXJXaWR0aCkuZmlsbCgwKTtcbiAgICB0aGlzLm5vdGVzID0gW107XG4gICAgdGhpcy5hcHBlbmQoW10pO1xuXG4gICAgLy8gQ2xlYXIgdGhlIGNhbnZhc1xuICAgIHRoaXMucmVzaXplKCk7XG5cbiAgICAvLyBTdGFydCBkcmF3aW5nXG4gICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoMCk7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kIHRoZSBjYW52YXNcbiAgICovXG4gIGFwcGVuZENhbnZhcyhwYXJlbnQpIHtcbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudCB8fCBkb2N1bWVudC5ib2R5O1xuICAgIHRoaXMuY2FudmFzID0gdGhpcy5jYW52YXMgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICB0aGlzLmN0eCA9IHRoaXMuY3R4IHx8IHRoaXMuY2FudmFzLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICB0aGlzLnBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLmNhbnZhcyk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgbmV4dCBmcmFtZVxuICAgKi9cbiAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZyYW1lKSB7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKChmcmFtZSkgPT4ge1xuICAgICAgdGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnJhbWUpO1xuICAgIH0pO1xuICAgIHRoaXMucGFpbnQoZnJhbWUpO1xuICAgIHRoaXMubGFzdEZyYW1lID0gZnJhbWU7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHdpbmRvdyByZXNpemVcbiAgICovXG4gIHJlc2l6ZSgpIHtcbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHRoaXMuaGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIHRoZSBjYW52YXNcbiAgICovXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY3R4LmNsZWFyUmVjdCgwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmQgdmFsdWVzXG4gICAqL1xuICBhcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcykge1xuICAgIHRoaXMubGFzdEFwcGVuZFRpbWUgPSB0aW1lO1xuICAgIHRoaXMubGFzdEFwcGVuZEZyYW1lID0gdGhpcy5sYXN0RnJhbWU7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlc1xuICAgICAgLmZpbHRlcigodmFsdWUpID0+IHZhbHVlICYmIHZhbHVlWzBdIDwgdGltZSlcbiAgICAgIC5jb25jYXQodmFsdWVzKVxuICAgICAgLnNsaWNlKC10aGlzLmNhbnZhcy53aWR0aClcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG5cbiAgICBpZiAobm90ZXM/Lmxlbmd0aCkge1xuICAgICAgdGhpcy5ub3RlcyA9IHRoaXMubm90ZXNcbiAgICAgICAgLmNvbmNhdChub3RlcylcbiAgICAgICAgLnNsaWNlKC01MClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGFbMF0gLSBiWzBdKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGFpbnQgdGhlIGNhbnZhc1xuICAgKi9cbiAgcGFpbnQoZnJhbWUpIHtcbiAgICB0aGlzLmNsZWFyKCk7XG4gICAgdGhpcy5kcmF3UmVsYWJpV2F2ZShmcmFtZSk7XG4gICAgdGhpcy5kcmF3Qm91bmRzKCk7XG4gICAgdGhpcy5kcmF3Tm90ZXMoZnJhbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIGJvdW5kc1xuICAgKi9cbiAgZHJhd0JvdW5kcygpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgLy8gRHJhdyBkYXNoZWQgbGluZXMgZm9yIGFsbCBib3VuZHNcbiAgICBmb3IgKGNvbnN0IGJvdW5kIG9mIHRoaXMucmVsYWJpLmJvdW5kcykge1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQoYm91bmQubGV2ZWwsIGhlaWdodCk7XG5cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5zZXRMaW5lRGFzaChbNCwgNF0pO1xuICAgICAgY3R4LmxpbmVXaWR0aCA9IDE7XG4gICAgICBjdHguc3Ryb2tlU3R5bGUgPSBib3VuZC5jb2xvciB8fCBcIiM4ODhcIjtcbiAgICAgIGN0eC5tb3ZlVG8oMCwgeSk7XG4gICAgICBjdHgubGluZVRvKHdpZHRoLCB5KTtcbiAgICAgIGN0eC5zdHJva2UoKTtcbiAgICB9XG5cbiAgICAvLyBEcmF3IHRoZSB6ZXJvIHBvc2l0aW9uXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5zZXRMaW5lRGFzaChbMSwgMV0pO1xuICAgIGN0eC5saW5lV2lkdGggPSAyO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiIzY2NlwiO1xuICAgIGN0eC5tb3ZlVG8od2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0LCAwKTtcbiAgICBjdHgubGluZVRvKHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCwgaGVpZ2h0KTtcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgcmVsYWJpIHdhdmVcbiAgICovXG4gIGRyYXdSZWxhYmlXYXZlKGZyYW1lKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIGNvbnN0IHBvaW50Q291bnQgPSB0aGlzLnZhbHVlcy5sZW5ndGg7XG4gICAgbGV0IGluZGV4ID0gMDtcblxuICAgIC8vIFN0YXJ0IHRoZSBwYXRoXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgIGN0eC5zdHJva2VTdHlsZSA9IFwiI2RmZlwiO1xuICAgIGN0eC5saW5lV2lkdGggPSAxLjE7XG4gICAgY3R4LnNldExpbmVEYXNoKFtdKTtcblxuICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBpbiBzZWNvbmRzIGZyb20gdGhlIGxhc3QgZnJhbWUgd2UgY29tcHV0ZWRcbiAgICBjb25zdCBmcmFtZU9mZnNldCA9IChmcmFtZSAtIHRoaXMubGFzdEFwcGVuZEZyYW1lKSAvIDEwMDA7XG5cbiAgICAvLyBNYWtlIGEgcGF0aCBjb25uZWN0aW5nIGFsbCB2YWx1ZXNcbiAgICBmb3IgKGNvbnN0IHBvaW50IG9mIHRoaXMudmFsdWVzKSB7XG4gICAgICBpZiAoIXBvaW50KSB7XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gcG9pbnQ7XG5cbiAgICAgIC8vIFRoaXMgaXMgdGhlIG9mZnNldCBvZiB0aGlzIHRpbWUgZnJvbSBjdXJyZW50IHRpbWVcbiAgICAgIC8vIElmIHRoaXMgaXMgaW4gdGhlIGZ1dHVyZSwgaXQgd2lsbCBiZSBwb3NpdGl2ZS5cbiAgICAgIC8vIFN1YnRyYWN0aW5nIHRoZSBmcmFtZSBvZmZzZXQgcHVsbHMgaXQgbmVnYXRpdmUuXG4gICAgICBjb25zdCB0aW1lT2Zmc2V0ID0gdGhpcy5sYXN0QXBwZW5kVGltZSArIGZyYW1lT2Zmc2V0IC0gdGltZTtcblxuICAgICAgY29uc3QgeCA9IHdpZHRoIC0gdGltZU9mZnNldCAqIHRoaXMuc3BlZWQgKiB3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQ7XG4gICAgICBjb25zdCB5ID0gZ2V0V2F2ZUhlaWdodCh2YWx1ZSwgaGVpZ2h0KTtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgY3R4Lm1vdmVUbyh4LCB5KTtcbiAgICAgIH1cbiAgICAgIGN0eC5saW5lVG8oeCwgeSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cblxuICAgIC8vIFBhaW50IHRoZSBsaW5lXG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIG5vdGVzXG4gICAqL1xuICBkcmF3Tm90ZXMoZnJhbWUpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IGluIHNlY29uZHMgZnJvbSB0aGUgbGFzdCBmcmFtZSB3ZSBjb21wdXRlZFxuICAgIGNvbnN0IGZyYW1lT2Zmc2V0ID0gKGZyYW1lIC0gdGhpcy5sYXN0QXBwZW5kRnJhbWUpIC8gMTAwMDtcblxuICAgIC8vIE1ha2UgYSBwYXRoIGNvbm5lY3RpbmcgYWxsIHZhbHVlc1xuICAgIGZvciAoY29uc3Qgbm90ZSBvZiB0aGlzLm5vdGVzKSB7XG4gICAgICBjb25zdCBbdGltZSwgdmFsdWUsIGRpcmVjdGlvbl0gPSBub3RlO1xuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRoaXMubGFzdEFwcGVuZFRpbWUgKyBmcmFtZU9mZnNldCAtIHRpbWU7XG4gICAgICBjb25zdCB4ID0gd2lkdGggLSB0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoIC0gdGhpcy50WmVyb09mZnNldDtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KHZhbHVlLCBoZWlnaHQpO1xuXG4gICAgICAvLyBEb24ndCBkcmF3IG5vdGVzIHRoYXQgaGF2ZW4ndCBwbGF5ZWQgeWV0XG4gICAgICBpZiAoeCA+IHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gRHJhdyBub3RlcyBhcyBhIGRvdCB0aGF0IGZhZGVzIG91dFxuICAgICAgY29uc3Qgb3BhY2l0eSA9IDEgLSAodGltZU9mZnNldCAqIHRoaXMuc3BlZWQgKiB3aWR0aCkgLyAxMDAwO1xuICAgICAgaWYgKG9wYWNpdHkgPCAwLjAwMSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5hcmMoeCAtIE5PVEVfUkFESVVTIC8gNCwgeSwgTk9URV9SQURJVVMsIDAsIDIgKiBNYXRoLlBJKTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSBkaXJlY3Rpb25cbiAgICAgICAgPyBgcmdiYSgyNTUsOTYsMTI4LCR7b3BhY2l0eX0pYFxuICAgICAgICA6IGByZ2JhKDEyOCwyNTUsOTYsJHtvcGFjaXR5fSlgO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiB0aGUgd2F2ZSBhdCBhIGdpdmVuIHZhbHVlXG4gKi9cbmNvbnN0IGdldFdhdmVIZWlnaHQgPSAodmFsdWUsIGhlaWdodCkgPT4gKCh2YWx1ZSArIDEpIC8gMikgKiBoZWlnaHQ7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5cbmNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5jb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigwLjMpO1xuY29tcHJlc3Nvci5jb25uZWN0KGdhaW4pO1xuZ2Fpbi50b0Rlc3RpbmF0aW9uKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNvbXByZXNzb3I7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgeyBjaG9pY2UsIHJhbmRyYW5nZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IFBMQVlFUl9DT1VOVCA9IDQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNhbXBsZXIge1xuICBjb25zdHJ1Y3Rvcih7IHNhbXBsZXMsIHRvbmFsIH0pIHtcbiAgICB0aGlzLnRvbmFsID0gdG9uYWw7XG4gICAgdGhpcy5zYW1wbGVzID0gc2FtcGxlcy5tYXAoKHsgLi4uc2FtcGxlIH0pID0+IHtcbiAgICAgIHNhbXBsZS5wbGF5ZXJzID0gW107XG4gICAgICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUExBWUVSX0NPVU5UOyBpKyspIHtcbiAgICAgICAgbGV0IGZuID0gc2FtcGxlLmZuO1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgICAgIGZuID0gXCIvL2FzZGYudXMva2FsaW1iYS9cIiArIGZuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgICAgIHVybDogZm4sXG4gICAgICAgICAgcmV0cmlnZ2VyOiB0cnVlLFxuICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBsYXllci5jb25uZWN0KG91dHB1dCk7XG4gICAgICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW1wbGU7XG4gICAgfSk7XG4gIH1cblxuICBwbGF5KHRpbWUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VuZCA9IG9wdGlvbnMuaW5kZXhcbiAgICAgID8gdGhpcy5zYW1wbGVzW29wdGlvbnMuaW5kZXhdXG4gICAgICA6IGNob2ljZSh0aGlzLnNhbXBsZXMpO1xuXG4gICAgc291bmQuaW5kZXggPSAoc291bmQuaW5kZXggKyAxKSAlIFBMQVlFUl9DT1VOVDtcblxuICAgIGNvbnN0IHBsYXllciA9IHNvdW5kLnBsYXllcnNbc291bmQuaW5kZXhdO1xuXG4gICAgaWYgKHRoaXMudG9uYWwpIHtcbiAgICAgIHBsYXllci5wbGF5YmFja1JhdGUgPVxuICAgICAgICAob3B0aW9ucy5mcmVxdWVuY3kgKiBjaG9pY2UoWzAuNSwgMV0pICsgcmFuZHJhbmdlKDAsIDEwKSkgLyBzb3VuZC5yb290O1xuICAgIH1cblxuICAgIHBsYXllci5zdGFydCh0aW1lIHx8IDApO1xuICB9XG59XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9zYW1wbGVyXCI7XG5cbmV4cG9ydCBjb25zdCBLYWxpbWJhID0gbmV3IFNhbXBsZXIoe1xuICB0b25hbDogdHJ1ZSxcbiAgc2FtcGxlczogW1xuICAgIHsgcm9vdDogMjI2LCBmbjogXCJzYW1wbGVzLzM4MDczN19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDEtYS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAzNDAsIGZuOiBcInNhbXBsZXMvMzgwNzM1X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMy1lLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogNDUyLCBmbjogXCJzYW1wbGVzLzM4MDczM19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDYtYS0wMi1yYXcubXAzXCIgfSxcbiAgXSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRHJ1bXMgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFtcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2JkLm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19jbGFwLm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19jaC5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfcmltLm1wM1wiIH0sXG4gIF0sXG59KTtcblxuZXhwb3J0IGNvbnN0IEtpY2sgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFt7IGZuOiBcInNhbXBsZXMvNzA3X2JkLm1wM1wiIH0sIHsgZm46IFwic2FtcGxlcy83MDdfYmQyLm1wM1wiIH1dLFxufSk7XG5cbmV4cG9ydCBjb25zdCBTbmFyZSA9IG5ldyBTYW1wbGVyKHtcbiAgc2FtcGxlczogW3sgZm46IFwic2FtcGxlcy83MDdfc25hcmUxLm1wM1wiIH0sIHsgZm46IFwic2FtcGxlcy83MDdfc25hcmUyLm1wM1wiIH1dLFxufSk7XG5cbmV4cG9ydCBjb25zdCBIYXQgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFtcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NoLm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19jaC5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfY2gubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X29oLm1wM1wiIH0sXG4gIF0sXG59KTtcblxuZXhwb3J0IGNvbnN0IFBlcmMgPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFt7IGZuOiBcInNhbXBsZXMvNzA3X3JpbS5tcDNcIiB9LCB7IGZuOiBcInNhbXBsZXMvNzA3X3RhbWIubXAzXCIgfV0sXG59KTtcblxuZXhwb3J0IGNvbnN0IEN5bWJhbCA9IG5ldyBTYW1wbGVyKHtcbiAgc2FtcGxlczogW3sgZm46IFwic2FtcGxlcy83MDdfY3Jhc2gubXAzXCIgfSwgeyBmbjogXCJzYW1wbGVzLzcwN19yaWRlLm1wM1wiIH1dLFxufSk7XG5cbmV4cG9ydCBjb25zdCBUb20gPSBuZXcgU2FtcGxlcih7XG4gIHNhbXBsZXM6IFt7IGZuOiBcInNhbXBsZXMvNzA3X3RvbTEubXAzXCIgfSwgeyBmbjogXCJzYW1wbGVzLzcwN190b20yLm1wM1wiIH1dLFxufSk7XG4iLCIvKipcbiAqIFJlbGFiaSBldmVudCBnZW5lcmF0b3JcbiAqL1xuXG5pbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgUmVsYWJpQ2FudmFzIGZyb20gXCIuL2NhbnZhc1wiO1xuaW1wb3J0ICogYXMgSW5zdHJ1bWVudHMgZnJvbSBcIi4uL2xpYi9pbnN0cnVtZW50c1wiO1xuXG5jb25zdCBUV09fUEkgPSAyICogTWF0aC5QSTtcblxuLyoqXG4gKiBXYXZlIGZ1bmN0aW9uc1xuICovXG5jb25zdCBXQVZFX1NIQVBFUyA9IHtcbiAgc2luZTogTWF0aC5jb3MsXG4gIHRyaWFuZ2xlOiAodGltZSkgPT5cbiAgICAoNCAvIFRXT19QSSkgKlxuICAgICAgTWF0aC5hYnMoXG4gICAgICAgICgoKCh0aW1lIC0gVFdPX1BJIC8gNCkgJSBUV09fUEkpICsgVFdPX1BJKSAlIFRXT19QSSkgLSBUV09fUEkgLyAyXG4gICAgICApIC1cbiAgICAxLFxuICBzcXVhcmU6ICh0aW1lKSA9PiAodGltZSAlIFRXT19QSSA8IE1hdGguUEkgPyAxIDogLTEpLFxuICBzYXc6ICh0aW1lKSA9PiAodGltZSAlIFRXT19QSSkgLyBNYXRoLlBJIC0gMSxcbiAgcmV2ZXJzZV9zYXc6ICh0aW1lKSA9PiAxIC0gKHRpbWUgJSBUV09fUEkpIC8gTWF0aC5QSSxcbn07XG5cbi8qKlxuICogUmVsYWJpIGdlbmVyYXRvclxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWxhYmkge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSBnZW5lcmF0b3JcbiAgICovXG4gIGNvbnN0cnVjdG9yKHsgd2F2ZXMsIGJvdW5kcywgc2V0dGluZ3MsIHBhcmVudCB9KSB7XG4gICAgdGhpcy51cGRhdGVUaW1lID0gMTtcbiAgICB0aGlzLnN0ZXBzID0gNTA7XG4gICAgdGhpcy53YXZlcyA9IHdhdmVzO1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMuc2V0dGluZ3MgPSBzZXR0aW5ncztcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBudWxsO1xuICAgIHRoaXMuY2FudmFzID0gbmV3IFJlbGFiaUNhbnZhcyh7IHJlbGFiaTogdGhpcywgcGFyZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBnZW5lcmF0b3JcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnNvbGUubG9nKFwiU3RhcnQgUmVsYWJpXCIpO1xuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMuY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygodGltZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5nZW5lcmF0ZSh0aW1lKTtcbiAgICAgIGNvbnN0IG5vdGVzID0gdGhpcy5wbGF5KHZhbHVlcyk7XG4gICAgICB0aGlzLmNhbnZhcy5hcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcyk7XG4gICAgfSwgdGhpcy51cGRhdGVUaW1lKTtcbiAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgZ2VuZXJhdG9yIGFuZCByZXNldCBpdFxuICAgKi9cbiAgc3RvcCgpIHtcbiAgICBpZiAodGhpcy5jbG9jaykge1xuICAgICAgdGhpcy5jbG9jay5zdG9wKCk7XG4gICAgICB0aGlzLmNsb2NrLmRpc3Bvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcmVsYWJpIGV2ZW50c1xuICAgKi9cbiAgZ2VuZXJhdGUodGltZSkge1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgdmFsdWU7XG4gICAgbGV0IHZhbHVlcyA9IFtdO1xuICAgIGxldCBwcmV2aW91c1dhdmVWYWx1ZSA9IHRoaXMucHJldmlvdXNXYXZlVmFsdWUgfHwgMDtcblxuICAgIC8vIFdlaWdodCBpbmRpdmlkdWFsIHdhdmVzIHJhdGhlciB0aGFuIHNpbXBseSBhdmVyYWdpbmcgdGhlbVxuICAgIGxldCB0b3RhbFdlaWdodCA9IHRoaXMud2F2ZXMucmVkdWNlKChzdW0sIHdhdmUpID0+IHN1bSArIHdhdmUud2VpZ2h0LCAwLjApO1xuXG4gICAgLy8gT3ZlcnNob290IHRoZSBsaW5lIHNsaWdodGx5IGVhY2ggdGltZVxuICAgIGxldCBzdGVwQ291bnQgPSB0aGlzLnN0ZXBzO1xuXG4gICAgLy8gR2VuZXJhdGUgc2V2ZXJhbCBldmVudHMgcGVyIHNlY29uZFxuICAgIGZvciAoc3RlcCA9IDA7IHN0ZXAgPCBzdGVwQ291bnQ7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gVGltZSBvZmZzZXQgZm9yIHRoaXMgZXZlbnRcbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aW1lICsgKHN0ZXAgKiB0aGlzLnVwZGF0ZVRpbWUpIC8gdGhpcy5zdGVwcztcblxuICAgICAgLy8gSW5pdGlhbGl6ZSB2YWx1ZVxuICAgICAgdmFsdWUgPSAwO1xuXG4gICAgICAvLyBDb21wdXRlIHRoZSB3YXZlIGZ1bmN0aW9ucyBmb3IgdGhpcyBldmVudFxuICAgICAgZm9yIChjb25zdCB3YXZlIG9mIHRoaXMud2F2ZXMpIHtcbiAgICAgICAgY29uc3Qgd2F2ZU9mZnNldCA9XG4gICAgICAgICAgKHdhdmUub2Zmc2V0IHx8IDApICtcbiAgICAgICAgICAod2F2ZS5mcmVxdWVuY3kgKiB0aGlzLnNldHRpbmdzLnNwZWVkKSAvIHRoaXMuc3RlcHMgK1xuICAgICAgICAgIHByZXZpb3VzV2F2ZVZhbHVlICogdGhpcy5zZXR0aW5ncy5mZWVkYmFjaztcblxuICAgICAgICBjb25zdCB3YXZlVmFsdWUgPSBXQVZFX1NIQVBFU1t3YXZlLnNoYXBlXSh3YXZlT2Zmc2V0KTtcbiAgICAgICAgdmFsdWUgKz0gd2F2ZVZhbHVlICogd2F2ZS53ZWlnaHQ7XG4gICAgICAgIHByZXZpb3VzV2F2ZVZhbHVlID0gd2F2ZVZhbHVlO1xuICAgICAgICB3YXZlLm9mZnNldCA9IHdhdmVPZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFNjYWxlIHRvIFstMSwgMV1cbiAgICAgIHZhbHVlIC89IHRvdGFsV2VpZ2h0O1xuICAgICAgcHJldmlvdXNXYXZlVmFsdWUgPSB2YWx1ZTtcblxuICAgICAgdmFsdWVzLnB1c2goW3RpbWVPZmZzZXQsIHZhbHVlXSk7XG4gICAgfVxuXG4gICAgdGhpcy5wcmV2aW91c1dhdmVWYWx1ZSA9IHByZXZpb3VzV2F2ZVZhbHVlO1xuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBwbGF5KHZhbHVlcykge1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgbm90ZUNvdW50ID0gMDtcbiAgICBjb25zdCBub3RlcyA9IFtdO1xuXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gR2V0IHRoZSBuZXh0IHZhbHVlXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gdmFsdWVzW3N0ZXBdO1xuXG4gICAgICAvLyBDb21wdXRlIHdoZXRoZXIgd2UgY3Jvc3NlZCBhIGJvdW5kYXJ5LCBhbmQgd2hpY2ggZGlyZWN0aW9uXG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBib3VuZHNDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBib3VuZCA9IHRoaXMuYm91bmRzW2luZGV4XTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlIDwgYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIodGltZSwgYm91bmQuc291bmRzWzBdKTtcbiAgICAgICAgICBub3Rlcy5wdXNoKFt0aW1lLCBib3VuZC5sZXZlbCwgdHJ1ZV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHZhbHVlID4gYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA+IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIHVwXG4gICAgICAgICAgdGhpcy50cmlnZ2VyKHRpbWUsIGJvdW5kLnNvdW5kc1sxXSk7XG4gICAgICAgICAgbm90ZXMucHVzaChbdGltZSwgYm91bmQubGV2ZWwsIGZhbHNlXSk7XG4gICAgICAgICAgbm90ZUNvdW50ICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgcHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSBsYXRlc3QgdmFsdWVcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgLy8gUmV0dXJuIHRoZSBub3Rlc1xuICAgIHJldHVybiBub3RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGV2ZW50XG4gICAqL1xuICB0cmlnZ2VyKHRpbWUsIHNvdW5kKSB7XG4gICAgLy8gY29uc29sZS5sb2coXCJ0cmlnZ2VyIGluZGV4XCIsIGluZGV4LCB0aW1lKTtcbiAgICBpZiAoc291bmQuaW5zdHJ1bWVudCBpbiBJbnN0cnVtZW50cykge1xuICAgICAgSW5zdHJ1bWVudHNbc291bmQuaW5zdHJ1bWVudF0ucGxheSh0aW1lLCBzb3VuZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNvdW5kLmluc3RydW1lbnQucGxheSh0aW1lLCBzb3VuZCk7XG4gICAgfVxuICB9XG59XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfdHlwZW9mKG9iaikge1xuICBcIkBiYWJlbC9oZWxwZXJzIC0gdHlwZW9mXCI7XG5cbiAgcmV0dXJuIF90eXBlb2YgPSBcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFN5bWJvbCAmJiBcInN5bWJvbFwiID09IHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPyBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmo7XG4gIH0gOiBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIG9iaiAmJiBcImZ1bmN0aW9uXCIgPT0gdHlwZW9mIFN5bWJvbCAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajtcbiAgfSwgX3R5cGVvZihvYmopO1xufSIsImltcG9ydCBfdHlwZW9mIGZyb20gXCIuL3R5cGVvZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3RvUHJpbWl0aXZlKGlucHV0LCBoaW50KSB7XG4gIGlmIChfdHlwZW9mKGlucHV0KSAhPT0gXCJvYmplY3RcIiB8fCBpbnB1dCA9PT0gbnVsbCkgcmV0dXJuIGlucHV0O1xuICB2YXIgcHJpbSA9IGlucHV0W1N5bWJvbC50b1ByaW1pdGl2ZV07XG4gIGlmIChwcmltICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgcmVzID0gcHJpbS5jYWxsKGlucHV0LCBoaW50IHx8IFwiZGVmYXVsdFwiKTtcbiAgICBpZiAoX3R5cGVvZihyZXMpICE9PSBcIm9iamVjdFwiKSByZXR1cm4gcmVzO1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJAQHRvUHJpbWl0aXZlIG11c3QgcmV0dXJuIGEgcHJpbWl0aXZlIHZhbHVlLlwiKTtcbiAgfVxuICByZXR1cm4gKGhpbnQgPT09IFwic3RyaW5nXCIgPyBTdHJpbmcgOiBOdW1iZXIpKGlucHV0KTtcbn0iLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiLi90eXBlb2YuanNcIjtcbmltcG9ydCB0b1ByaW1pdGl2ZSBmcm9tIFwiLi90b1ByaW1pdGl2ZS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7XG4gIHZhciBrZXkgPSB0b1ByaW1pdGl2ZShhcmcsIFwic3RyaW5nXCIpO1xuICByZXR1cm4gX3R5cGVvZihrZXkpID09PSBcInN5bWJvbFwiID8ga2V5IDogU3RyaW5nKGtleSk7XG59IiwiaW1wb3J0IHRvUHJvcGVydHlLZXkgZnJvbSBcIi4vdG9Qcm9wZXJ0eUtleS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkge1xuICBrZXkgPSB0b1Byb3BlcnR5S2V5KGtleSk7XG4gIGlmIChrZXkgaW4gb2JqKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmpba2V5XSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiBvYmo7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2FycmF5TGlrZVRvQXJyYXkoYXJyLCBsZW4pIHtcbiAgaWYgKGxlbiA9PSBudWxsIHx8IGxlbiA+IGFyci5sZW5ndGgpIGxlbiA9IGFyci5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwLCBhcnIyID0gbmV3IEFycmF5KGxlbik7IGkgPCBsZW47IGkrKykgYXJyMltpXSA9IGFycltpXTtcbiAgcmV0dXJuIGFycjI7XG59IiwiaW1wb3J0IGFycmF5TGlrZVRvQXJyYXkgZnJvbSBcIi4vYXJyYXlMaWtlVG9BcnJheS5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2FycmF5V2l0aG91dEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShhcnIpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICBpZiAodHlwZW9mIFN5bWJvbCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBpdGVyW1N5bWJvbC5pdGVyYXRvcl0gIT0gbnVsbCB8fCBpdGVyW1wiQEBpdGVyYXRvclwiXSAhPSBudWxsKSByZXR1cm4gQXJyYXkuZnJvbShpdGVyKTtcbn0iLCJpbXBvcnQgYXJyYXlMaWtlVG9BcnJheSBmcm9tIFwiLi9hcnJheUxpa2VUb0FycmF5LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7XG4gIGlmICghbykgcmV0dXJuO1xuICBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBhcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gIHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTtcbiAgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gIGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9ub25JdGVyYWJsZVNwcmVhZCgpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgYXR0ZW1wdCB0byBzcHJlYWQgbm9uLWl0ZXJhYmxlIGluc3RhbmNlLlxcbkluIG9yZGVyIHRvIGJlIGl0ZXJhYmxlLCBub24tYXJyYXkgb2JqZWN0cyBtdXN0IGhhdmUgYSBbU3ltYm9sLml0ZXJhdG9yXSgpIG1ldGhvZC5cIik7XG59IiwiaW1wb3J0IGFycmF5V2l0aG91dEhvbGVzIGZyb20gXCIuL2FycmF5V2l0aG91dEhvbGVzLmpzXCI7XG5pbXBvcnQgaXRlcmFibGVUb0FycmF5IGZyb20gXCIuL2l0ZXJhYmxlVG9BcnJheS5qc1wiO1xuaW1wb3J0IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IGZyb20gXCIuL3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5LmpzXCI7XG5pbXBvcnQgbm9uSXRlcmFibGVTcHJlYWQgZnJvbSBcIi4vbm9uSXRlcmFibGVTcHJlYWQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHtcbiAgcmV0dXJuIGFycmF5V2l0aG91dEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5KGFycikgfHwgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkoYXJyKSB8fCBub25JdGVyYWJsZVNwcmVhZCgpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB7XG4gIHZhciBfaSA9IG51bGwgPT0gYXJyID8gbnVsbCA6IFwidW5kZWZpbmVkXCIgIT0gdHlwZW9mIFN5bWJvbCAmJiBhcnJbU3ltYm9sLml0ZXJhdG9yXSB8fCBhcnJbXCJAQGl0ZXJhdG9yXCJdO1xuICBpZiAobnVsbCAhPSBfaSkge1xuICAgIHZhciBfcyxcbiAgICAgIF9lLFxuICAgICAgX3gsXG4gICAgICBfcixcbiAgICAgIF9hcnIgPSBbXSxcbiAgICAgIF9uID0gITAsXG4gICAgICBfZCA9ICExO1xuICAgIHRyeSB7XG4gICAgICBpZiAoX3ggPSAoX2kgPSBfaS5jYWxsKGFycikpLm5leHQsIDAgPT09IGkpIHtcbiAgICAgICAgaWYgKE9iamVjdChfaSkgIT09IF9pKSByZXR1cm47XG4gICAgICAgIF9uID0gITE7XG4gICAgICB9IGVsc2UgZm9yICg7ICEoX24gPSAoX3MgPSBfeC5jYWxsKF9pKSkuZG9uZSkgJiYgKF9hcnIucHVzaChfcy52YWx1ZSksIF9hcnIubGVuZ3RoICE9PSBpKTsgX24gPSAhMCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBfZCA9ICEwLCBfZSA9IGVycjtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFfbiAmJiBudWxsICE9IF9pW1wicmV0dXJuXCJdICYmIChfciA9IF9pW1wicmV0dXJuXCJdKCksIE9iamVjdChfcikgIT09IF9yKSkgcmV0dXJuO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgaWYgKF9kKSB0aHJvdyBfZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9hcnI7XG4gIH1cbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufSIsImltcG9ydCBhcnJheVdpdGhIb2xlcyBmcm9tIFwiLi9hcnJheVdpdGhIb2xlcy5qc1wiO1xuaW1wb3J0IGl0ZXJhYmxlVG9BcnJheUxpbWl0IGZyb20gXCIuL2l0ZXJhYmxlVG9BcnJheUxpbWl0LmpzXCI7XG5pbXBvcnQgdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkgZnJvbSBcIi4vdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanNcIjtcbmltcG9ydCBub25JdGVyYWJsZVJlc3QgZnJvbSBcIi4vbm9uSXRlcmFibGVSZXN0LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfc2xpY2VkVG9BcnJheShhcnIsIGkpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5TGltaXQoYXJyLCBpKSB8fCB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheShhcnIsIGkpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufSIsIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbnZhciB3YXJuZWQgPSB7fTtcbnZhciBwcmVXYXJuaW5nRm5zID0gW107XG5cbi8qKlxuICogUHJlIHdhcm5pbmcgZW5hYmxlIHlvdSB0byBwYXJzZSBjb250ZW50IGJlZm9yZSBjb25zb2xlLmVycm9yLlxuICogTW9kaWZ5IHRvIG51bGwgd2lsbCBwcmV2ZW50IHdhcm5pbmcuXG4gKi9cbmV4cG9ydCB2YXIgcHJlTWVzc2FnZSA9IGZ1bmN0aW9uIHByZU1lc3NhZ2UoZm4pIHtcbiAgcHJlV2FybmluZ0Zucy5wdXNoKGZuKTtcbn07XG5leHBvcnQgZnVuY3Rpb24gd2FybmluZyh2YWxpZCwgbWVzc2FnZSkge1xuICAvLyBTdXBwb3J0IHVnbGlmeVxuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiAhdmFsaWQgJiYgY29uc29sZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFyIGZpbmFsTWVzc2FnZSA9IHByZVdhcm5pbmdGbnMucmVkdWNlKGZ1bmN0aW9uIChtc2csIHByZU1lc3NhZ2VGbikge1xuICAgICAgcmV0dXJuIHByZU1lc3NhZ2VGbihtc2cgIT09IG51bGwgJiYgbXNnICE9PSB2b2lkIDAgPyBtc2cgOiAnJywgJ3dhcm5pbmcnKTtcbiAgICB9LCBtZXNzYWdlKTtcbiAgICBpZiAoZmluYWxNZXNzYWdlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiV2FybmluZzogXCIuY29uY2F0KGZpbmFsTWVzc2FnZSkpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIG5vdGUodmFsaWQsIG1lc3NhZ2UpIHtcbiAgLy8gU3VwcG9ydCB1Z2xpZnlcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgJiYgIXZhbGlkICYmIGNvbnNvbGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBmaW5hbE1lc3NhZ2UgPSBwcmVXYXJuaW5nRm5zLnJlZHVjZShmdW5jdGlvbiAobXNnLCBwcmVNZXNzYWdlRm4pIHtcbiAgICAgIHJldHVybiBwcmVNZXNzYWdlRm4obXNnICE9PSBudWxsICYmIG1zZyAhPT0gdm9pZCAwID8gbXNnIDogJycsICdub3RlJyk7XG4gICAgfSwgbWVzc2FnZSk7XG4gICAgaWYgKGZpbmFsTWVzc2FnZSkge1xuICAgICAgY29uc29sZS53YXJuKFwiTm90ZTogXCIuY29uY2F0KGZpbmFsTWVzc2FnZSkpO1xuICAgIH1cbiAgfVxufVxuZXhwb3J0IGZ1bmN0aW9uIHJlc2V0V2FybmVkKCkge1xuICB3YXJuZWQgPSB7fTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjYWxsKG1ldGhvZCwgdmFsaWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWxpZCAmJiAhd2FybmVkW21lc3NhZ2VdKSB7XG4gICAgbWV0aG9kKGZhbHNlLCBtZXNzYWdlKTtcbiAgICB3YXJuZWRbbWVzc2FnZV0gPSB0cnVlO1xuICB9XG59XG5leHBvcnQgZnVuY3Rpb24gd2FybmluZ09uY2UodmFsaWQsIG1lc3NhZ2UpIHtcbiAgY2FsbCh3YXJuaW5nLCB2YWxpZCwgbWVzc2FnZSk7XG59XG5leHBvcnQgZnVuY3Rpb24gbm90ZU9uY2UodmFsaWQsIG1lc3NhZ2UpIHtcbiAgY2FsbChub3RlLCB2YWxpZCwgbWVzc2FnZSk7XG59XG53YXJuaW5nT25jZS5wcmVNZXNzYWdlID0gcHJlTWVzc2FnZTtcbndhcm5pbmdPbmNlLnJlc2V0V2FybmVkID0gcmVzZXRXYXJuZWQ7XG53YXJuaW5nT25jZS5ub3RlT25jZSA9IG5vdGVPbmNlO1xuZXhwb3J0IGRlZmF1bHQgd2FybmluZ09uY2U7XG4vKiBlc2xpbnQtZW5hYmxlICovIiwiaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuaW1wb3J0IHdhcm5pbmcgZnJvbSBcIi4vd2FybmluZ1wiO1xuXG4vKipcbiAqIERlZXBseSBjb21wYXJlcyB0d28gb2JqZWN0IGxpdGVyYWxzLlxuICogQHBhcmFtIG9iajEgb2JqZWN0IDFcbiAqIEBwYXJhbSBvYmoyIG9iamVjdCAyXG4gKiBAcGFyYW0gc2hhbGxvdyBzaGFsbG93IGNvbXBhcmVcbiAqIEByZXR1cm5zXG4gKi9cbmZ1bmN0aW9uIGlzRXF1YWwob2JqMSwgb2JqMikge1xuICB2YXIgc2hhbGxvdyA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDogZmFsc2U7XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvbWFwYm94LWdsLWpzL3B1bGwvNTk3OS9maWxlcyNkaWZmLWZkZTcxNDUwNTBjNDdjYzNhMzA2ODU2ZWZkNWY5YzMwMTZlODZlODU5ZGU5YWZiZDAyYzg3OWJlNTA2N2U1OGZcbiAgdmFyIHJlZlNldCA9IG5ldyBTZXQoKTtcbiAgZnVuY3Rpb24gZGVlcEVxdWFsKGEsIGIpIHtcbiAgICB2YXIgbGV2ZWwgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IDE7XG4gICAgdmFyIGNpcmN1bGFyID0gcmVmU2V0LmhhcyhhKTtcbiAgICB3YXJuaW5nKCFjaXJjdWxhciwgJ1dhcm5pbmc6IFRoZXJlIG1heSBiZSBjaXJjdWxhciByZWZlcmVuY2VzJyk7XG4gICAgaWYgKGNpcmN1bGFyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChhID09PSBiKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHNoYWxsb3cgJiYgbGV2ZWwgPiAxKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJlZlNldC5hZGQoYSk7XG4gICAgdmFyIG5ld0xldmVsID0gbGV2ZWwgKyAxO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGEpKSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYikgfHwgYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWRlZXBFcXVhbChhW2ldLCBiW2ldLCBuZXdMZXZlbCkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoYSAmJiBiICYmIF90eXBlb2YoYSkgPT09ICdvYmplY3QnICYmIF90eXBlb2YoYikgPT09ICdvYmplY3QnKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGEpO1xuICAgICAgaWYgKGtleXMubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGtleXMuZXZlcnkoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICByZXR1cm4gZGVlcEVxdWFsKGFba2V5XSwgYltrZXldLCBuZXdMZXZlbCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gb3RoZXJcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIGRlZXBFcXVhbChvYmoxLCBvYmoyKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGlzRXF1YWw7IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlRXZlbnQoY2FsbGJhY2spIHtcbiAgdmFyIGZuUmVmID0gUmVhY3QudXNlUmVmKCk7XG4gIGZuUmVmLmN1cnJlbnQgPSBjYWxsYmFjaztcbiAgdmFyIG1lbW9GbiA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgX2ZuUmVmJGN1cnJlbnQ7XG4gICAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cbiAgICByZXR1cm4gKF9mblJlZiRjdXJyZW50ID0gZm5SZWYuY3VycmVudCkgPT09IG51bGwgfHwgX2ZuUmVmJGN1cnJlbnQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9mblJlZiRjdXJyZW50LmNhbGwuYXBwbHkoX2ZuUmVmJGN1cnJlbnQsIFtmblJlZl0uY29uY2F0KGFyZ3MpKTtcbiAgfSwgW10pO1xuICByZXR1cm4gbWVtb0ZuO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNhblVzZURvbSgpIHtcbiAgcmV0dXJuICEhKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5kb2N1bWVudCAmJiB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNhblVzZURvbSBmcm9tIFwiLi4vRG9tL2NhblVzZURvbVwiO1xuXG4vKipcbiAqIFdyYXAgYFJlYWN0LnVzZUxheW91dEVmZmVjdGAgd2hpY2ggd2lsbCBub3QgdGhyb3cgd2FybmluZyBtZXNzYWdlIGluIHRlc3QgZW52XG4gKi9cbnZhciB1c2VMYXlvdXRFZmZlY3QgPSBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnICYmIGNhblVzZURvbSgpID8gUmVhY3QudXNlTGF5b3V0RWZmZWN0IDogUmVhY3QudXNlRWZmZWN0O1xuZXhwb3J0IGRlZmF1bHQgdXNlTGF5b3V0RWZmZWN0O1xuZXhwb3J0IHZhciB1c2VMYXlvdXRVcGRhdGVFZmZlY3QgPSBmdW5jdGlvbiB1c2VMYXlvdXRVcGRhdGVFZmZlY3QoY2FsbGJhY2ssIGRlcHMpIHtcbiAgdmFyIGZpcnN0TW91bnRSZWYgPSBSZWFjdC51c2VSZWYodHJ1ZSk7XG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFmaXJzdE1vdW50UmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgIH1cbiAgfSwgZGVwcyk7XG5cbiAgLy8gV2UgdGVsbCByZWFjdCB0aGF0IGZpcnN0IG1vdW50IGhhcyBwYXNzZWRcbiAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBmaXJzdE1vdW50UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgZmlyc3RNb3VudFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9O1xuICB9LCBbXSk7XG59OyIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuLyoqXG4gKiBTYW1lIGFzIFJlYWN0LnVzZVN0YXRlIGJ1dCBgc2V0U3RhdGVgIGFjY2VwdCBgaWdub3JlRGVzdHJveWAgcGFyYW0gdG8gbm90IHRvIHNldFN0YXRlIGFmdGVyIGRlc3Ryb3llZC5cbiAqIFdlIGRvIG5vdCBtYWtlIHRoaXMgYXV0byBpcyB0byBhdm9pZCByZWFsIG1lbW9yeSBsZWFrLlxuICogRGV2ZWxvcGVyIHNob3VsZCBjb25maXJtIGl0J3Mgc2FmZSB0byBpZ25vcmUgdGhlbXNlbHZlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlU2FmZVN0YXRlKGRlZmF1bHRWYWx1ZSkge1xuICB2YXIgZGVzdHJveVJlZiA9IFJlYWN0LnVzZVJlZihmYWxzZSk7XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZShkZWZhdWx0VmFsdWUpLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDIpLFxuICAgIHZhbHVlID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRWYWx1ZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMV07XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgZGVzdHJveVJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRlc3Ryb3lSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfTtcbiAgfSwgW10pO1xuICBmdW5jdGlvbiBzYWZlU2V0U3RhdGUodXBkYXRlciwgaWdub3JlRGVzdHJveSkge1xuICAgIGlmIChpZ25vcmVEZXN0cm95ICYmIGRlc3Ryb3lSZWYuY3VycmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZXRWYWx1ZSh1cGRhdGVyKTtcbiAgfVxuICByZXR1cm4gW3ZhbHVlLCBzYWZlU2V0U3RhdGVdO1xufSIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IHVzZUV2ZW50IGZyb20gXCIuL3VzZUV2ZW50XCI7XG5pbXBvcnQgeyB1c2VMYXlvdXRVcGRhdGVFZmZlY3QgfSBmcm9tIFwiLi91c2VMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCB1c2VTdGF0ZSBmcm9tIFwiLi91c2VTdGF0ZVwiO1xuLyoqIFdlIG9ubHkgdGhpbmsgYHVuZGVmaW5lZGAgaXMgZW1wdHkgKi9cbmZ1bmN0aW9uIGhhc1ZhbHVlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFNpbWlsYXIgdG8gYHVzZVN0YXRlYCBidXQgd2lsbCB1c2UgcHJvcHMgdmFsdWUgaWYgcHJvdmlkZWQuXG4gKiBOb3RlIHRoYXQgaW50ZXJuYWwgdXNlIHJjLXV0aWwgYHVzZVN0YXRlYCBob29rLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VNZXJnZWRTdGF0ZShkZWZhdWx0U3RhdGVWYWx1ZSwgb3B0aW9uKSB7XG4gIHZhciBfcmVmID0gb3B0aW9uIHx8IHt9LFxuICAgIGRlZmF1bHRWYWx1ZSA9IF9yZWYuZGVmYXVsdFZhbHVlLFxuICAgIHZhbHVlID0gX3JlZi52YWx1ZSxcbiAgICBvbkNoYW5nZSA9IF9yZWYub25DaGFuZ2UsXG4gICAgcG9zdFN0YXRlID0gX3JlZi5wb3N0U3RhdGU7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT0gSW5pdCA9PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgX3VzZVN0YXRlID0gdXNlU3RhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGhhc1ZhbHVlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9IGVsc2UgaWYgKGhhc1ZhbHVlKGRlZmF1bHRWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBkZWZhdWx0VmFsdWUgPT09ICdmdW5jdGlvbicgPyBkZWZhdWx0VmFsdWUoKSA6IGRlZmF1bHRWYWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgZGVmYXVsdFN0YXRlVmFsdWUgPT09ICdmdW5jdGlvbicgPyBkZWZhdWx0U3RhdGVWYWx1ZSgpIDogZGVmYXVsdFN0YXRlVmFsdWU7XG4gICAgICB9XG4gICAgfSksXG4gICAgX3VzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF91c2VTdGF0ZSwgMiksXG4gICAgaW5uZXJWYWx1ZSA9IF91c2VTdGF0ZTJbMF0sXG4gICAgc2V0SW5uZXJWYWx1ZSA9IF91c2VTdGF0ZTJbMV07XG4gIHZhciBtZXJnZWRWYWx1ZSA9IHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IGlubmVyVmFsdWU7XG4gIHZhciBwb3N0TWVyZ2VkVmFsdWUgPSBwb3N0U3RhdGUgPyBwb3N0U3RhdGUobWVyZ2VkVmFsdWUpIDogbWVyZ2VkVmFsdWU7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PSBDaGFuZ2UgPT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgb25DaGFuZ2VGbiA9IHVzZUV2ZW50KG9uQ2hhbmdlKTtcbiAgdmFyIF91c2VTdGF0ZTMgPSB1c2VTdGF0ZShbbWVyZ2VkVmFsdWVdKSxcbiAgICBfdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0YXRlMywgMiksXG4gICAgcHJldlZhbHVlID0gX3VzZVN0YXRlNFswXSxcbiAgICBzZXRQcmV2VmFsdWUgPSBfdXNlU3RhdGU0WzFdO1xuICB1c2VMYXlvdXRVcGRhdGVFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHZhciBwcmV2ID0gcHJldlZhbHVlWzBdO1xuICAgIGlmIChpbm5lclZhbHVlICE9PSBwcmV2KSB7XG4gICAgICBvbkNoYW5nZUZuKGlubmVyVmFsdWUsIHByZXYpO1xuICAgIH1cbiAgfSwgW3ByZXZWYWx1ZV0pO1xuXG4gIC8vIFN5bmMgdmFsdWUgYmFjayB0byBgdW5kZWZpbmVkYCB3aGVuIGl0IGZyb20gY29udHJvbCB0byB1bi1jb250cm9sXG4gIHVzZUxheW91dFVwZGF0ZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFoYXNWYWx1ZSh2YWx1ZSkpIHtcbiAgICAgIHNldElubmVyVmFsdWUodmFsdWUpO1xuICAgIH1cbiAgfSwgW3ZhbHVlXSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PSBVcGRhdGUgPT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgdHJpZ2dlckNoYW5nZSA9IHVzZUV2ZW50KGZ1bmN0aW9uICh1cGRhdGVyLCBpZ25vcmVEZXN0cm95KSB7XG4gICAgc2V0SW5uZXJWYWx1ZSh1cGRhdGVyLCBpZ25vcmVEZXN0cm95KTtcbiAgICBzZXRQcmV2VmFsdWUoW21lcmdlZFZhbHVlXSwgaWdub3JlRGVzdHJveSk7XG4gIH0pO1xuICByZXR1cm4gW3Bvc3RNZXJnZWRWYWx1ZSwgdHJpZ2dlckNoYW5nZV07XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2V4dGVuZHMoKSB7XG4gIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiA/IE9iamVjdC5hc3NpZ24uYmluZCgpIDogZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCkge1xuICBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTtcbiAgdmFyIHRhcmdldCA9IHt9O1xuICB2YXIgc291cmNlS2V5cyA9IE9iamVjdC5rZXlzKHNvdXJjZSk7XG4gIHZhciBrZXksIGk7XG4gIGZvciAoaSA9IDA7IGkgPCBzb3VyY2VLZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAga2V5ID0gc291cmNlS2V5c1tpXTtcbiAgICBpZiAoZXhjbHVkZWQuaW5kZXhPZihrZXkpID49IDApIGNvbnRpbnVlO1xuICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gIH1cbiAgcmV0dXJuIHRhcmdldDtcbn0iLCJpbXBvcnQgb2JqZWN0V2l0aG91dFByb3BlcnRpZXNMb29zZSBmcm9tIFwiLi9vYmplY3RXaXRob3V0UHJvcGVydGllc0xvb3NlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoc291cmNlLCBleGNsdWRlZCkge1xuICBpZiAoc291cmNlID09IG51bGwpIHJldHVybiB7fTtcbiAgdmFyIHRhcmdldCA9IG9iamVjdFdpdGhvdXRQcm9wZXJ0aWVzTG9vc2Uoc291cmNlLCBleGNsdWRlZCk7XG4gIHZhciBrZXksIGk7XG4gIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gICAgdmFyIHNvdXJjZVN5bWJvbEtleXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHNvdXJjZSk7XG4gICAgZm9yIChpID0gMDsgaSA8IHNvdXJjZVN5bWJvbEtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGtleSA9IHNvdXJjZVN5bWJvbEtleXNbaV07XG4gICAgICBpZiAoZXhjbHVkZWQuaW5kZXhPZihrZXkpID49IDApIGNvbnRpbnVlO1xuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoc291cmNlLCBrZXkpKSBjb250aW51ZTtcbiAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59IiwiaW1wb3J0IGRlZmluZVByb3BlcnR5IGZyb20gXCIuL2RlZmluZVByb3BlcnR5LmpzXCI7XG5mdW5jdGlvbiBvd25LZXlzKG9iamVjdCwgZW51bWVyYWJsZU9ubHkpIHtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICAgIHZhciBzeW1ib2xzID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhvYmplY3QpO1xuICAgIGVudW1lcmFibGVPbmx5ICYmIChzeW1ib2xzID0gc3ltYm9scy5maWx0ZXIoZnVuY3Rpb24gKHN5bSkge1xuICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBzeW0pLmVudW1lcmFibGU7XG4gICAgfSkpLCBrZXlzLnB1c2guYXBwbHkoa2V5cywgc3ltYm9scyk7XG4gIH1cbiAgcmV0dXJuIGtleXM7XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfb2JqZWN0U3ByZWFkMih0YXJnZXQpIHtcbiAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgc291cmNlID0gbnVsbCAhPSBhcmd1bWVudHNbaV0gPyBhcmd1bWVudHNbaV0gOiB7fTtcbiAgICBpICUgMiA/IG93bktleXMoT2JqZWN0KHNvdXJjZSksICEwKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBzb3VyY2Vba2V5XSk7XG4gICAgfSkgOiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoc291cmNlKSkgOiBvd25LZXlzKE9iamVjdChzb3VyY2UpKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIGtleSkpO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiB0YXJnZXQ7XG59IiwiLyoqXG4gKiBAaWdub3JlXG4gKiBzb21lIGtleS1jb2RlcyBkZWZpbml0aW9uIGFuZCB1dGlscyBmcm9tIGNsb3N1cmUtbGlicmFyeVxuICogQGF1dGhvciB5aW1pbmdoZUBnbWFpbC5jb21cbiAqL1xuXG52YXIgS2V5Q29kZSA9IHtcbiAgLyoqXG4gICAqIE1BQ19FTlRFUlxuICAgKi9cbiAgTUFDX0VOVEVSOiAzLFxuICAvKipcbiAgICogQkFDS1NQQUNFXG4gICAqL1xuICBCQUNLU1BBQ0U6IDgsXG4gIC8qKlxuICAgKiBUQUJcbiAgICovXG4gIFRBQjogOSxcbiAgLyoqXG4gICAqIE5VTUxPQ0sgb24gRkYvU2FmYXJpIE1hY1xuICAgKi9cbiAgTlVNX0NFTlRFUjogMTIsXG4gIC8vIE5VTUxPQ0sgb24gRkYvU2FmYXJpIE1hY1xuICAvKipcbiAgICogRU5URVJcbiAgICovXG4gIEVOVEVSOiAxMyxcbiAgLyoqXG4gICAqIFNISUZUXG4gICAqL1xuICBTSElGVDogMTYsXG4gIC8qKlxuICAgKiBDVFJMXG4gICAqL1xuICBDVFJMOiAxNyxcbiAgLyoqXG4gICAqIEFMVFxuICAgKi9cbiAgQUxUOiAxOCxcbiAgLyoqXG4gICAqIFBBVVNFXG4gICAqL1xuICBQQVVTRTogMTksXG4gIC8qKlxuICAgKiBDQVBTX0xPQ0tcbiAgICovXG4gIENBUFNfTE9DSzogMjAsXG4gIC8qKlxuICAgKiBFU0NcbiAgICovXG4gIEVTQzogMjcsXG4gIC8qKlxuICAgKiBTUEFDRVxuICAgKi9cbiAgU1BBQ0U6IDMyLFxuICAvKipcbiAgICogUEFHRV9VUFxuICAgKi9cbiAgUEFHRV9VUDogMzMsXG4gIC8vIGFsc28gTlVNX05PUlRIX0VBU1RcbiAgLyoqXG4gICAqIFBBR0VfRE9XTlxuICAgKi9cbiAgUEFHRV9ET1dOOiAzNCxcbiAgLy8gYWxzbyBOVU1fU09VVEhfRUFTVFxuICAvKipcbiAgICogRU5EXG4gICAqL1xuICBFTkQ6IDM1LFxuICAvLyBhbHNvIE5VTV9TT1VUSF9XRVNUXG4gIC8qKlxuICAgKiBIT01FXG4gICAqL1xuICBIT01FOiAzNixcbiAgLy8gYWxzbyBOVU1fTk9SVEhfV0VTVFxuICAvKipcbiAgICogTEVGVFxuICAgKi9cbiAgTEVGVDogMzcsXG4gIC8vIGFsc28gTlVNX1dFU1RcbiAgLyoqXG4gICAqIFVQXG4gICAqL1xuICBVUDogMzgsXG4gIC8vIGFsc28gTlVNX05PUlRIXG4gIC8qKlxuICAgKiBSSUdIVFxuICAgKi9cbiAgUklHSFQ6IDM5LFxuICAvLyBhbHNvIE5VTV9FQVNUXG4gIC8qKlxuICAgKiBET1dOXG4gICAqL1xuICBET1dOOiA0MCxcbiAgLy8gYWxzbyBOVU1fU09VVEhcbiAgLyoqXG4gICAqIFBSSU5UX1NDUkVFTlxuICAgKi9cbiAgUFJJTlRfU0NSRUVOOiA0NCxcbiAgLyoqXG4gICAqIElOU0VSVFxuICAgKi9cbiAgSU5TRVJUOiA0NSxcbiAgLy8gYWxzbyBOVU1fSU5TRVJUXG4gIC8qKlxuICAgKiBERUxFVEVcbiAgICovXG4gIERFTEVURTogNDYsXG4gIC8vIGFsc28gTlVNX0RFTEVURVxuICAvKipcbiAgICogWkVST1xuICAgKi9cbiAgWkVSTzogNDgsXG4gIC8qKlxuICAgKiBPTkVcbiAgICovXG4gIE9ORTogNDksXG4gIC8qKlxuICAgKiBUV09cbiAgICovXG4gIFRXTzogNTAsXG4gIC8qKlxuICAgKiBUSFJFRVxuICAgKi9cbiAgVEhSRUU6IDUxLFxuICAvKipcbiAgICogRk9VUlxuICAgKi9cbiAgRk9VUjogNTIsXG4gIC8qKlxuICAgKiBGSVZFXG4gICAqL1xuICBGSVZFOiA1MyxcbiAgLyoqXG4gICAqIFNJWFxuICAgKi9cbiAgU0lYOiA1NCxcbiAgLyoqXG4gICAqIFNFVkVOXG4gICAqL1xuICBTRVZFTjogNTUsXG4gIC8qKlxuICAgKiBFSUdIVFxuICAgKi9cbiAgRUlHSFQ6IDU2LFxuICAvKipcbiAgICogTklORVxuICAgKi9cbiAgTklORTogNTcsXG4gIC8qKlxuICAgKiBRVUVTVElPTl9NQVJLXG4gICAqL1xuICBRVUVTVElPTl9NQVJLOiA2MyxcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBBXG4gICAqL1xuICBBOiA2NSxcbiAgLyoqXG4gICAqIEJcbiAgICovXG4gIEI6IDY2LFxuICAvKipcbiAgICogQ1xuICAgKi9cbiAgQzogNjcsXG4gIC8qKlxuICAgKiBEXG4gICAqL1xuICBEOiA2OCxcbiAgLyoqXG4gICAqIEVcbiAgICovXG4gIEU6IDY5LFxuICAvKipcbiAgICogRlxuICAgKi9cbiAgRjogNzAsXG4gIC8qKlxuICAgKiBHXG4gICAqL1xuICBHOiA3MSxcbiAgLyoqXG4gICAqIEhcbiAgICovXG4gIEg6IDcyLFxuICAvKipcbiAgICogSVxuICAgKi9cbiAgSTogNzMsXG4gIC8qKlxuICAgKiBKXG4gICAqL1xuICBKOiA3NCxcbiAgLyoqXG4gICAqIEtcbiAgICovXG4gIEs6IDc1LFxuICAvKipcbiAgICogTFxuICAgKi9cbiAgTDogNzYsXG4gIC8qKlxuICAgKiBNXG4gICAqL1xuICBNOiA3NyxcbiAgLyoqXG4gICAqIE5cbiAgICovXG4gIE46IDc4LFxuICAvKipcbiAgICogT1xuICAgKi9cbiAgTzogNzksXG4gIC8qKlxuICAgKiBQXG4gICAqL1xuICBQOiA4MCxcbiAgLyoqXG4gICAqIFFcbiAgICovXG4gIFE6IDgxLFxuICAvKipcbiAgICogUlxuICAgKi9cbiAgUjogODIsXG4gIC8qKlxuICAgKiBTXG4gICAqL1xuICBTOiA4MyxcbiAgLyoqXG4gICAqIFRcbiAgICovXG4gIFQ6IDg0LFxuICAvKipcbiAgICogVVxuICAgKi9cbiAgVTogODUsXG4gIC8qKlxuICAgKiBWXG4gICAqL1xuICBWOiA4NixcbiAgLyoqXG4gICAqIFdcbiAgICovXG4gIFc6IDg3LFxuICAvKipcbiAgICogWFxuICAgKi9cbiAgWDogODgsXG4gIC8qKlxuICAgKiBZXG4gICAqL1xuICBZOiA4OSxcbiAgLyoqXG4gICAqIFpcbiAgICovXG4gIFo6IDkwLFxuICAvKipcbiAgICogTUVUQVxuICAgKi9cbiAgTUVUQTogOTEsXG4gIC8vIFdJTl9LRVlfTEVGVFxuICAvKipcbiAgICogV0lOX0tFWV9SSUdIVFxuICAgKi9cbiAgV0lOX0tFWV9SSUdIVDogOTIsXG4gIC8qKlxuICAgKiBDT05URVhUX01FTlVcbiAgICovXG4gIENPTlRFWFRfTUVOVTogOTMsXG4gIC8qKlxuICAgKiBOVU1fWkVST1xuICAgKi9cbiAgTlVNX1pFUk86IDk2LFxuICAvKipcbiAgICogTlVNX09ORVxuICAgKi9cbiAgTlVNX09ORTogOTcsXG4gIC8qKlxuICAgKiBOVU1fVFdPXG4gICAqL1xuICBOVU1fVFdPOiA5OCxcbiAgLyoqXG4gICAqIE5VTV9USFJFRVxuICAgKi9cbiAgTlVNX1RIUkVFOiA5OSxcbiAgLyoqXG4gICAqIE5VTV9GT1VSXG4gICAqL1xuICBOVU1fRk9VUjogMTAwLFxuICAvKipcbiAgICogTlVNX0ZJVkVcbiAgICovXG4gIE5VTV9GSVZFOiAxMDEsXG4gIC8qKlxuICAgKiBOVU1fU0lYXG4gICAqL1xuICBOVU1fU0lYOiAxMDIsXG4gIC8qKlxuICAgKiBOVU1fU0VWRU5cbiAgICovXG4gIE5VTV9TRVZFTjogMTAzLFxuICAvKipcbiAgICogTlVNX0VJR0hUXG4gICAqL1xuICBOVU1fRUlHSFQ6IDEwNCxcbiAgLyoqXG4gICAqIE5VTV9OSU5FXG4gICAqL1xuICBOVU1fTklORTogMTA1LFxuICAvKipcbiAgICogTlVNX01VTFRJUExZXG4gICAqL1xuICBOVU1fTVVMVElQTFk6IDEwNixcbiAgLyoqXG4gICAqIE5VTV9QTFVTXG4gICAqL1xuICBOVU1fUExVUzogMTA3LFxuICAvKipcbiAgICogTlVNX01JTlVTXG4gICAqL1xuICBOVU1fTUlOVVM6IDEwOSxcbiAgLyoqXG4gICAqIE5VTV9QRVJJT0RcbiAgICovXG4gIE5VTV9QRVJJT0Q6IDExMCxcbiAgLyoqXG4gICAqIE5VTV9ESVZJU0lPTlxuICAgKi9cbiAgTlVNX0RJVklTSU9OOiAxMTEsXG4gIC8qKlxuICAgKiBGMVxuICAgKi9cbiAgRjE6IDExMixcbiAgLyoqXG4gICAqIEYyXG4gICAqL1xuICBGMjogMTEzLFxuICAvKipcbiAgICogRjNcbiAgICovXG4gIEYzOiAxMTQsXG4gIC8qKlxuICAgKiBGNFxuICAgKi9cbiAgRjQ6IDExNSxcbiAgLyoqXG4gICAqIEY1XG4gICAqL1xuICBGNTogMTE2LFxuICAvKipcbiAgICogRjZcbiAgICovXG4gIEY2OiAxMTcsXG4gIC8qKlxuICAgKiBGN1xuICAgKi9cbiAgRjc6IDExOCxcbiAgLyoqXG4gICAqIEY4XG4gICAqL1xuICBGODogMTE5LFxuICAvKipcbiAgICogRjlcbiAgICovXG4gIEY5OiAxMjAsXG4gIC8qKlxuICAgKiBGMTBcbiAgICovXG4gIEYxMDogMTIxLFxuICAvKipcbiAgICogRjExXG4gICAqL1xuICBGMTE6IDEyMixcbiAgLyoqXG4gICAqIEYxMlxuICAgKi9cbiAgRjEyOiAxMjMsXG4gIC8qKlxuICAgKiBOVU1MT0NLXG4gICAqL1xuICBOVU1MT0NLOiAxNDQsXG4gIC8qKlxuICAgKiBTRU1JQ09MT05cbiAgICovXG4gIFNFTUlDT0xPTjogMTg2LFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIERBU0hcbiAgICovXG4gIERBU0g6IDE4OSxcbiAgLy8gbmVlZHMgbG9jYWxpemF0aW9uXG4gIC8qKlxuICAgKiBFUVVBTFNcbiAgICovXG4gIEVRVUFMUzogMTg3LFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIENPTU1BXG4gICAqL1xuICBDT01NQTogMTg4LFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIFBFUklPRFxuICAgKi9cbiAgUEVSSU9EOiAxOTAsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogU0xBU0hcbiAgICovXG4gIFNMQVNIOiAxOTEsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogQVBPU1RST1BIRVxuICAgKi9cbiAgQVBPU1RST1BIRTogMTkyLFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIFNJTkdMRV9RVU9URVxuICAgKi9cbiAgU0lOR0xFX1FVT1RFOiAyMjIsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogT1BFTl9TUVVBUkVfQlJBQ0tFVFxuICAgKi9cbiAgT1BFTl9TUVVBUkVfQlJBQ0tFVDogMjE5LFxuICAvLyBuZWVkcyBsb2NhbGl6YXRpb25cbiAgLyoqXG4gICAqIEJBQ0tTTEFTSFxuICAgKi9cbiAgQkFDS1NMQVNIOiAyMjAsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogQ0xPU0VfU1FVQVJFX0JSQUNLRVRcbiAgICovXG4gIENMT1NFX1NRVUFSRV9CUkFDS0VUOiAyMjEsXG4gIC8vIG5lZWRzIGxvY2FsaXphdGlvblxuICAvKipcbiAgICogV0lOX0tFWVxuICAgKi9cbiAgV0lOX0tFWTogMjI0LFxuICAvKipcbiAgICogTUFDX0ZGX01FVEFcbiAgICovXG4gIE1BQ19GRl9NRVRBOiAyMjQsXG4gIC8vIEZpcmVmb3ggKEdlY2tvKSBmaXJlcyB0aGlzIGZvciB0aGUgbWV0YSBrZXkgaW5zdGVhZCBvZiA5MVxuICAvKipcbiAgICogV0lOX0lNRVxuICAgKi9cbiAgV0lOX0lNRTogMjI5LFxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT0gRnVuY3Rpb24gPT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8qKlxuICAgKiB3aGV0aGVyIHRleHQgYW5kIG1vZGlmaWVkIGtleSBpcyBlbnRlcmVkIGF0IHRoZSBzYW1lIHRpbWUuXG4gICAqL1xuICBpc1RleHRNb2RpZnlpbmdLZXlFdmVudDogZnVuY3Rpb24gaXNUZXh0TW9kaWZ5aW5nS2V5RXZlbnQoZSkge1xuICAgIHZhciBrZXlDb2RlID0gZS5rZXlDb2RlO1xuICAgIGlmIChlLmFsdEtleSAmJiAhZS5jdHJsS2V5IHx8IGUubWV0YUtleSB8fFxuICAgIC8vIEZ1bmN0aW9uIGtleXMgZG9uJ3QgZ2VuZXJhdGUgdGV4dFxuICAgIGtleUNvZGUgPj0gS2V5Q29kZS5GMSAmJiBrZXlDb2RlIDw9IEtleUNvZGUuRjEyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gVGhlIGZvbGxvd2luZyBrZXlzIGFyZSBxdWl0ZSBoYXJtbGVzcywgZXZlbiBpbiBjb21iaW5hdGlvbiB3aXRoXG4gICAgLy8gQ1RSTCwgQUxUIG9yIFNISUZULlxuICAgIHN3aXRjaCAoa2V5Q29kZSkge1xuICAgICAgY2FzZSBLZXlDb2RlLkFMVDpcbiAgICAgIGNhc2UgS2V5Q29kZS5DQVBTX0xPQ0s6XG4gICAgICBjYXNlIEtleUNvZGUuQ09OVEVYVF9NRU5VOlxuICAgICAgY2FzZSBLZXlDb2RlLkNUUkw6XG4gICAgICBjYXNlIEtleUNvZGUuRE9XTjpcbiAgICAgIGNhc2UgS2V5Q29kZS5FTkQ6XG4gICAgICBjYXNlIEtleUNvZGUuRVNDOlxuICAgICAgY2FzZSBLZXlDb2RlLkhPTUU6XG4gICAgICBjYXNlIEtleUNvZGUuSU5TRVJUOlxuICAgICAgY2FzZSBLZXlDb2RlLkxFRlQ6XG4gICAgICBjYXNlIEtleUNvZGUuTUFDX0ZGX01FVEE6XG4gICAgICBjYXNlIEtleUNvZGUuTUVUQTpcbiAgICAgIGNhc2UgS2V5Q29kZS5OVU1MT0NLOlxuICAgICAgY2FzZSBLZXlDb2RlLk5VTV9DRU5URVI6XG4gICAgICBjYXNlIEtleUNvZGUuUEFHRV9ET1dOOlxuICAgICAgY2FzZSBLZXlDb2RlLlBBR0VfVVA6XG4gICAgICBjYXNlIEtleUNvZGUuUEFVU0U6XG4gICAgICBjYXNlIEtleUNvZGUuUFJJTlRfU0NSRUVOOlxuICAgICAgY2FzZSBLZXlDb2RlLlJJR0hUOlxuICAgICAgY2FzZSBLZXlDb2RlLlNISUZUOlxuICAgICAgY2FzZSBLZXlDb2RlLlVQOlxuICAgICAgY2FzZSBLZXlDb2RlLldJTl9LRVk6XG4gICAgICBjYXNlIEtleUNvZGUuV0lOX0tFWV9SSUdIVDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogd2hldGhlciBjaGFyYWN0ZXIgaXMgZW50ZXJlZC5cbiAgICovXG4gIGlzQ2hhcmFjdGVyS2V5OiBmdW5jdGlvbiBpc0NoYXJhY3RlcktleShrZXlDb2RlKSB7XG4gICAgaWYgKGtleUNvZGUgPj0gS2V5Q29kZS5aRVJPICYmIGtleUNvZGUgPD0gS2V5Q29kZS5OSU5FKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGtleUNvZGUgPj0gS2V5Q29kZS5OVU1fWkVSTyAmJiBrZXlDb2RlIDw9IEtleUNvZGUuTlVNX01VTFRJUExZKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGtleUNvZGUgPj0gS2V5Q29kZS5BICYmIGtleUNvZGUgPD0gS2V5Q29kZS5aKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBTYWZhcmkgc2VuZHMgemVybyBrZXkgY29kZSBmb3Igbm9uLWxhdGluIGNoYXJhY3RlcnMuXG4gICAgaWYgKHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ1dlYktpdCcpICE9PSAtMSAmJiBrZXlDb2RlID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgc3dpdGNoIChrZXlDb2RlKSB7XG4gICAgICBjYXNlIEtleUNvZGUuU1BBQ0U6XG4gICAgICBjYXNlIEtleUNvZGUuUVVFU1RJT05fTUFSSzpcbiAgICAgIGNhc2UgS2V5Q29kZS5OVU1fUExVUzpcbiAgICAgIGNhc2UgS2V5Q29kZS5OVU1fTUlOVVM6XG4gICAgICBjYXNlIEtleUNvZGUuTlVNX1BFUklPRDpcbiAgICAgIGNhc2UgS2V5Q29kZS5OVU1fRElWSVNJT046XG4gICAgICBjYXNlIEtleUNvZGUuU0VNSUNPTE9OOlxuICAgICAgY2FzZSBLZXlDb2RlLkRBU0g6XG4gICAgICBjYXNlIEtleUNvZGUuRVFVQUxTOlxuICAgICAgY2FzZSBLZXlDb2RlLkNPTU1BOlxuICAgICAgY2FzZSBLZXlDb2RlLlBFUklPRDpcbiAgICAgIGNhc2UgS2V5Q29kZS5TTEFTSDpcbiAgICAgIGNhc2UgS2V5Q29kZS5BUE9TVFJPUEhFOlxuICAgICAgY2FzZSBLZXlDb2RlLlNJTkdMRV9RVU9URTpcbiAgICAgIGNhc2UgS2V5Q29kZS5PUEVOX1NRVUFSRV9CUkFDS0VUOlxuICAgICAgY2FzZSBLZXlDb2RlLkJBQ0tTTEFTSDpcbiAgICAgIGNhc2UgS2V5Q29kZS5DTE9TRV9TUVVBUkVfQlJBQ0tFVDpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59O1xuZXhwb3J0IGRlZmF1bHQgS2V5Q29kZTsiLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG52YXIgU2xpZGVyQ29udGV4dCA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVDb250ZXh0KHtcbiAgbWluOiAwLFxuICBtYXg6IDAsXG4gIGRpcmVjdGlvbjogJ2x0cicsXG4gIHN0ZXA6IDEsXG4gIGluY2x1ZGVkU3RhcnQ6IDAsXG4gIGluY2x1ZGVkRW5kOiAwLFxuICB0YWJJbmRleDogMCxcbiAga2V5Ym9hcmQ6IHRydWVcbn0pO1xuZXhwb3J0IGRlZmF1bHQgU2xpZGVyQ29udGV4dDsiLCJleHBvcnQgZnVuY3Rpb24gZ2V0T2Zmc2V0KHZhbHVlLCBtaW4sIG1heCkge1xuICByZXR1cm4gKHZhbHVlIC0gbWluKSAvIChtYXggLSBtaW4pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGdldERpcmVjdGlvblN0eWxlKGRpcmVjdGlvbiwgdmFsdWUsIG1pbiwgbWF4KSB7XG4gIHZhciBvZmZzZXQgPSBnZXRPZmZzZXQodmFsdWUsIG1pbiwgbWF4KTtcbiAgdmFyIHBvc2l0aW9uU3R5bGUgPSB7fTtcbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgICBjYXNlICdydGwnOlxuICAgICAgcG9zaXRpb25TdHlsZS5yaWdodCA9IFwiXCIuY29uY2F0KG9mZnNldCAqIDEwMCwgXCIlXCIpO1xuICAgICAgcG9zaXRpb25TdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCg1MCUpJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2J0dCc6XG4gICAgICBwb3NpdGlvblN0eWxlLmJvdHRvbSA9IFwiXCIuY29uY2F0KG9mZnNldCAqIDEwMCwgXCIlXCIpO1xuICAgICAgcG9zaXRpb25TdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWSg1MCUpJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3R0Yic6XG4gICAgICBwb3NpdGlvblN0eWxlLnRvcCA9IFwiXCIuY29uY2F0KG9mZnNldCAqIDEwMCwgXCIlXCIpO1xuICAgICAgcG9zaXRpb25TdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWSgtNTAlKSc7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgcG9zaXRpb25TdHlsZS5sZWZ0ID0gXCJcIi5jb25jYXQob2Zmc2V0ICogMTAwLCBcIiVcIik7XG4gICAgICBwb3NpdGlvblN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGVYKC01MCUpJztcbiAgICAgIGJyZWFrO1xuICB9XG4gIHJldHVybiBwb3NpdGlvblN0eWxlO1xufVxuLyoqIFJldHVybiBpbmRleCB2YWx1ZSBpZiBpcyBsaXN0IG9yIHJldHVybiB2YWx1ZSBkaXJlY3RseSAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEluZGV4KHZhbHVlLCBpbmRleCkge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZVtpbmRleF0gOiB2YWx1ZTtcbn0iLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJwcmVmaXhDbHNcIiwgXCJ2YWx1ZVwiLCBcInZhbHVlSW5kZXhcIiwgXCJvblN0YXJ0TW92ZVwiLCBcInN0eWxlXCIsIFwicmVuZGVyXCIsIFwiZHJhZ2dpbmdcIiwgXCJvbk9mZnNldENoYW5nZVwiXTtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IEtleUNvZGUgZnJvbSBcInJjLXV0aWwvZXMvS2V5Q29kZVwiO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5pbXBvcnQgeyBnZXREaXJlY3Rpb25TdHlsZSwgZ2V0SW5kZXggfSBmcm9tICcuLi91dGlsJztcbnZhciBIYW5kbGUgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICB2YXIgX2NsYXNzTmFtZXMsIF9nZXRJbmRleDtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICB2YWx1ZSA9IHByb3BzLnZhbHVlLFxuICAgIHZhbHVlSW5kZXggPSBwcm9wcy52YWx1ZUluZGV4LFxuICAgIG9uU3RhcnRNb3ZlID0gcHJvcHMub25TdGFydE1vdmUsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICByZW5kZXIgPSBwcm9wcy5yZW5kZXIsXG4gICAgZHJhZ2dpbmcgPSBwcm9wcy5kcmFnZ2luZyxcbiAgICBvbk9mZnNldENoYW5nZSA9IHByb3BzLm9uT2Zmc2V0Q2hhbmdlLFxuICAgIHJlc3RQcm9wcyA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhwcm9wcywgX2V4Y2x1ZGVkKTtcbiAgdmFyIF9SZWFjdCR1c2VDb250ZXh0ID0gUmVhY3QudXNlQ29udGV4dChTbGlkZXJDb250ZXh0KSxcbiAgICBtaW4gPSBfUmVhY3QkdXNlQ29udGV4dC5taW4sXG4gICAgbWF4ID0gX1JlYWN0JHVzZUNvbnRleHQubWF4LFxuICAgIGRpcmVjdGlvbiA9IF9SZWFjdCR1c2VDb250ZXh0LmRpcmVjdGlvbixcbiAgICBkaXNhYmxlZCA9IF9SZWFjdCR1c2VDb250ZXh0LmRpc2FibGVkLFxuICAgIGtleWJvYXJkID0gX1JlYWN0JHVzZUNvbnRleHQua2V5Ym9hcmQsXG4gICAgcmFuZ2UgPSBfUmVhY3QkdXNlQ29udGV4dC5yYW5nZSxcbiAgICB0YWJJbmRleCA9IF9SZWFjdCR1c2VDb250ZXh0LnRhYkluZGV4LFxuICAgIGFyaWFMYWJlbEZvckhhbmRsZSA9IF9SZWFjdCR1c2VDb250ZXh0LmFyaWFMYWJlbEZvckhhbmRsZSxcbiAgICBhcmlhTGFiZWxsZWRCeUZvckhhbmRsZSA9IF9SZWFjdCR1c2VDb250ZXh0LmFyaWFMYWJlbGxlZEJ5Rm9ySGFuZGxlLFxuICAgIGFyaWFWYWx1ZVRleHRGb3JtYXR0ZXJGb3JIYW5kbGUgPSBfUmVhY3QkdXNlQ29udGV4dC5hcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlO1xuICB2YXIgaGFuZGxlUHJlZml4Q2xzID0gXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1oYW5kbGVcIik7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gRXZlbnRzID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG9uSW50ZXJuYWxTdGFydE1vdmUgPSBmdW5jdGlvbiBvbkludGVybmFsU3RhcnRNb3ZlKGUpIHtcbiAgICBpZiAoIWRpc2FibGVkKSB7XG4gICAgICBvblN0YXJ0TW92ZShlLCB2YWx1ZUluZGV4KTtcbiAgICB9XG4gIH07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBLZXlib2FyZCA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG9uS2V5RG93biA9IGZ1bmN0aW9uIG9uS2V5RG93bihlKSB7XG4gICAgaWYgKCFkaXNhYmxlZCAmJiBrZXlib2FyZCkge1xuICAgICAgdmFyIG9mZnNldCA9IG51bGw7XG4gICAgICAvLyBDaGFuZ2UgdGhlIHZhbHVlXG4gICAgICBzd2l0Y2ggKGUud2hpY2ggfHwgZS5rZXlDb2RlKSB7XG4gICAgICAgIGNhc2UgS2V5Q29kZS5MRUZUOlxuICAgICAgICAgIG9mZnNldCA9IGRpcmVjdGlvbiA9PT0gJ2x0cicgfHwgZGlyZWN0aW9uID09PSAnYnR0JyA/IC0xIDogMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBLZXlDb2RlLlJJR0hUOlxuICAgICAgICAgIG9mZnNldCA9IGRpcmVjdGlvbiA9PT0gJ2x0cicgfHwgZGlyZWN0aW9uID09PSAnYnR0JyA/IDEgOiAtMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gVXAgaXMgcGx1c1xuICAgICAgICBjYXNlIEtleUNvZGUuVVA6XG4gICAgICAgICAgb2Zmc2V0ID0gZGlyZWN0aW9uICE9PSAndHRiJyA/IDEgOiAtMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gRG93biBpcyBtaW51c1xuICAgICAgICBjYXNlIEtleUNvZGUuRE9XTjpcbiAgICAgICAgICBvZmZzZXQgPSBkaXJlY3Rpb24gIT09ICd0dGInID8gLTEgOiAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEtleUNvZGUuSE9NRTpcbiAgICAgICAgICBvZmZzZXQgPSAnbWluJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBLZXlDb2RlLkVORDpcbiAgICAgICAgICBvZmZzZXQgPSAnbWF4JztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBLZXlDb2RlLlBBR0VfVVA6XG4gICAgICAgICAgb2Zmc2V0ID0gMjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBLZXlDb2RlLlBBR0VfRE9XTjpcbiAgICAgICAgICBvZmZzZXQgPSAtMjtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChvZmZzZXQgIT09IG51bGwpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBvbk9mZnNldENoYW5nZShvZmZzZXQsIHZhbHVlSW5kZXgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBPZmZzZXQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgcG9zaXRpb25TdHlsZSA9IGdldERpcmVjdGlvblN0eWxlKGRpcmVjdGlvbiwgdmFsdWUsIG1pbiwgbWF4KTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgaGFuZGxlTm9kZSA9IC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIF9leHRlbmRzKHtcbiAgICByZWY6IHJlZixcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMoaGFuZGxlUHJlZml4Q2xzLCAoX2NsYXNzTmFtZXMgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9jbGFzc05hbWVzLCBcIlwiLmNvbmNhdChoYW5kbGVQcmVmaXhDbHMsIFwiLVwiKS5jb25jYXQodmFsdWVJbmRleCArIDEpLCByYW5nZSksIF9kZWZpbmVQcm9wZXJ0eShfY2xhc3NOYW1lcywgXCJcIi5jb25jYXQoaGFuZGxlUHJlZml4Q2xzLCBcIi1kcmFnZ2luZ1wiKSwgZHJhZ2dpbmcpLCBfY2xhc3NOYW1lcykpLFxuICAgIHN0eWxlOiBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIHBvc2l0aW9uU3R5bGUpLCBzdHlsZSksXG4gICAgb25Nb3VzZURvd246IG9uSW50ZXJuYWxTdGFydE1vdmUsXG4gICAgb25Ub3VjaFN0YXJ0OiBvbkludGVybmFsU3RhcnRNb3ZlLFxuICAgIG9uS2V5RG93bjogb25LZXlEb3duLFxuICAgIHRhYkluZGV4OiBkaXNhYmxlZCA/IG51bGwgOiBnZXRJbmRleCh0YWJJbmRleCwgdmFsdWVJbmRleCksXG4gICAgcm9sZTogXCJzbGlkZXJcIixcbiAgICBcImFyaWEtdmFsdWVtaW5cIjogbWluLFxuICAgIFwiYXJpYS12YWx1ZW1heFwiOiBtYXgsXG4gICAgXCJhcmlhLXZhbHVlbm93XCI6IHZhbHVlLFxuICAgIFwiYXJpYS1kaXNhYmxlZFwiOiBkaXNhYmxlZCxcbiAgICBcImFyaWEtbGFiZWxcIjogZ2V0SW5kZXgoYXJpYUxhYmVsRm9ySGFuZGxlLCB2YWx1ZUluZGV4KSxcbiAgICBcImFyaWEtbGFiZWxsZWRieVwiOiBnZXRJbmRleChhcmlhTGFiZWxsZWRCeUZvckhhbmRsZSwgdmFsdWVJbmRleCksXG4gICAgXCJhcmlhLXZhbHVldGV4dFwiOiAoX2dldEluZGV4ID0gZ2V0SW5kZXgoYXJpYVZhbHVlVGV4dEZvcm1hdHRlckZvckhhbmRsZSwgdmFsdWVJbmRleCkpID09PSBudWxsIHx8IF9nZXRJbmRleCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2dldEluZGV4KHZhbHVlKVxuICB9LCByZXN0UHJvcHMpKTtcbiAgLy8gQ3VzdG9taXplXG4gIGlmIChyZW5kZXIpIHtcbiAgICBoYW5kbGVOb2RlID0gcmVuZGVyKGhhbmRsZU5vZGUsIHtcbiAgICAgIGluZGV4OiB2YWx1ZUluZGV4LFxuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBkcmFnZ2luZzogZHJhZ2dpbmdcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gaGFuZGxlTm9kZTtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgSGFuZGxlLmRpc3BsYXlOYW1lID0gJ0hhbmRsZSc7XG59XG5leHBvcnQgZGVmYXVsdCBIYW5kbGU7IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiO1xudmFyIF9leGNsdWRlZCA9IFtcInByZWZpeENsc1wiLCBcInN0eWxlXCIsIFwib25TdGFydE1vdmVcIiwgXCJvbk9mZnNldENoYW5nZVwiLCBcInZhbHVlc1wiLCBcImhhbmRsZVJlbmRlclwiLCBcImRyYWdnaW5nSW5kZXhcIl07XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgSGFuZGxlIGZyb20gJy4vSGFuZGxlJztcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSAnLi4vdXRpbCc7XG52YXIgSGFuZGxlcyA9IC8qI19fUFVSRV9fKi9SZWFjdC5mb3J3YXJkUmVmKGZ1bmN0aW9uIChwcm9wcywgcmVmKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICBvblN0YXJ0TW92ZSA9IHByb3BzLm9uU3RhcnRNb3ZlLFxuICAgIG9uT2Zmc2V0Q2hhbmdlID0gcHJvcHMub25PZmZzZXRDaGFuZ2UsXG4gICAgdmFsdWVzID0gcHJvcHMudmFsdWVzLFxuICAgIGhhbmRsZVJlbmRlciA9IHByb3BzLmhhbmRsZVJlbmRlcixcbiAgICBkcmFnZ2luZ0luZGV4ID0gcHJvcHMuZHJhZ2dpbmdJbmRleCxcbiAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIF9leGNsdWRlZCk7XG4gIHZhciBoYW5kbGVzUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgUmVhY3QudXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZm9jdXM6IGZ1bmN0aW9uIGZvY3VzKGluZGV4KSB7XG4gICAgICAgIHZhciBfaGFuZGxlc1JlZiRjdXJyZW50JGk7XG4gICAgICAgIChfaGFuZGxlc1JlZiRjdXJyZW50JGkgPSBoYW5kbGVzUmVmLmN1cnJlbnRbaW5kZXhdKSA9PT0gbnVsbCB8fCBfaGFuZGxlc1JlZiRjdXJyZW50JGkgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9oYW5kbGVzUmVmJGN1cnJlbnQkaS5mb2N1cygpO1xuICAgICAgfVxuICAgIH07XG4gIH0pO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3QuRnJhZ21lbnQsIG51bGwsIHZhbHVlcy5tYXAoZnVuY3Rpb24gKHZhbHVlLCBpbmRleCkge1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChIYW5kbGUsIF9leHRlbmRzKHtcbiAgICAgIHJlZjogZnVuY3Rpb24gcmVmKG5vZGUpIHtcbiAgICAgICAgaWYgKCFub2RlKSB7XG4gICAgICAgICAgZGVsZXRlIGhhbmRsZXNSZWYuY3VycmVudFtpbmRleF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGFuZGxlc1JlZi5jdXJyZW50W2luZGV4XSA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBkcmFnZ2luZzogZHJhZ2dpbmdJbmRleCA9PT0gaW5kZXgsXG4gICAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICAgIHN0eWxlOiBnZXRJbmRleChzdHlsZSwgaW5kZXgpLFxuICAgICAga2V5OiBpbmRleCxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIHZhbHVlSW5kZXg6IGluZGV4LFxuICAgICAgb25TdGFydE1vdmU6IG9uU3RhcnRNb3ZlLFxuICAgICAgb25PZmZzZXRDaGFuZ2U6IG9uT2Zmc2V0Q2hhbmdlLFxuICAgICAgcmVuZGVyOiBoYW5kbGVSZW5kZXJcbiAgICB9LCByZXN0UHJvcHMpKTtcbiAgfSkpO1xufSk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBIYW5kbGVzLmRpc3BsYXlOYW1lID0gJ0hhbmRsZXMnO1xufVxuZXhwb3J0IGRlZmF1bHQgSGFuZGxlczsiLCJpbXBvcnQgX3RvQ29uc3VtYWJsZUFycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0NvbnN1bWFibGVBcnJheVwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5mdW5jdGlvbiBnZXRQb3NpdGlvbihlKSB7XG4gIHZhciBvYmogPSAndG91Y2hlcycgaW4gZSA/IGUudG91Y2hlc1swXSA6IGU7XG4gIHJldHVybiB7XG4gICAgcGFnZVg6IG9iai5wYWdlWCxcbiAgICBwYWdlWTogb2JqLnBhZ2VZXG4gIH07XG59XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VEcmFnKGNvbnRhaW5lclJlZiwgZGlyZWN0aW9uLCByYXdWYWx1ZXMsIG1pbiwgbWF4LCBmb3JtYXRWYWx1ZSwgdHJpZ2dlckNoYW5nZSwgZmluaXNoQ2hhbmdlLCBvZmZzZXRWYWx1ZXMpIHtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKG51bGwpLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDIpLFxuICAgIGRyYWdnaW5nVmFsdWUgPSBfUmVhY3QkdXNlU3RhdGUyWzBdLFxuICAgIHNldERyYWdnaW5nVmFsdWUgPSBfUmVhY3QkdXNlU3RhdGUyWzFdO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlMyA9IFJlYWN0LnVzZVN0YXRlKC0xKSxcbiAgICBfUmVhY3QkdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMywgMiksXG4gICAgZHJhZ2dpbmdJbmRleCA9IF9SZWFjdCR1c2VTdGF0ZTRbMF0sXG4gICAgc2V0RHJhZ2dpbmdJbmRleCA9IF9SZWFjdCR1c2VTdGF0ZTRbMV07XG4gIHZhciBfUmVhY3QkdXNlU3RhdGU1ID0gUmVhY3QudXNlU3RhdGUocmF3VmFsdWVzKSxcbiAgICBfUmVhY3QkdXNlU3RhdGU2ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlNSwgMiksXG4gICAgY2FjaGVWYWx1ZXMgPSBfUmVhY3QkdXNlU3RhdGU2WzBdLFxuICAgIHNldENhY2hlVmFsdWVzID0gX1JlYWN0JHVzZVN0YXRlNlsxXTtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZTcgPSBSZWFjdC51c2VTdGF0ZShyYXdWYWx1ZXMpLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTggPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGU3LCAyKSxcbiAgICBvcmlnaW5WYWx1ZXMgPSBfUmVhY3QkdXNlU3RhdGU4WzBdLFxuICAgIHNldE9yaWdpblZhbHVlcyA9IF9SZWFjdCR1c2VTdGF0ZThbMV07XG4gIHZhciBtb3VzZU1vdmVFdmVudFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgdmFyIG1vdXNlVXBFdmVudFJlZiA9IFJlYWN0LnVzZVJlZihudWxsKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZHJhZ2dpbmdJbmRleCA9PT0gLTEpIHtcbiAgICAgIHNldENhY2hlVmFsdWVzKHJhd1ZhbHVlcyk7XG4gICAgfVxuICB9LCBbcmF3VmFsdWVzLCBkcmFnZ2luZ0luZGV4XSk7XG4gIC8vIENsZWFuIHVwIGV2ZW50XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG1vdXNlTW92ZUV2ZW50UmVmLmN1cnJlbnQpO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG1vdXNlVXBFdmVudFJlZi5jdXJyZW50KTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIG1vdXNlTW92ZUV2ZW50UmVmLmN1cnJlbnQpO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBtb3VzZVVwRXZlbnRSZWYuY3VycmVudCk7XG4gICAgfTtcbiAgfSwgW10pO1xuICB2YXIgZmx1c2hWYWx1ZXMgPSBmdW5jdGlvbiBmbHVzaFZhbHVlcyhuZXh0VmFsdWVzLCBuZXh0VmFsdWUpIHtcbiAgICAvLyBQZXJmOiBPbmx5IHVwZGF0ZSBzdGF0ZSB3aGVuIHZhbHVlIGNoYW5nZWRcbiAgICBpZiAoY2FjaGVWYWx1ZXMuc29tZShmdW5jdGlvbiAodmFsLCBpKSB7XG4gICAgICByZXR1cm4gdmFsICE9PSBuZXh0VmFsdWVzW2ldO1xuICAgIH0pKSB7XG4gICAgICBpZiAobmV4dFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2V0RHJhZ2dpbmdWYWx1ZShuZXh0VmFsdWUpO1xuICAgICAgfVxuICAgICAgc2V0Q2FjaGVWYWx1ZXMobmV4dFZhbHVlcyk7XG4gICAgICB0cmlnZ2VyQ2hhbmdlKG5leHRWYWx1ZXMpO1xuICAgIH1cbiAgfTtcbiAgdmFyIHVwZGF0ZUNhY2hlVmFsdWUgPSBmdW5jdGlvbiB1cGRhdGVDYWNoZVZhbHVlKHZhbHVlSW5kZXgsIG9mZnNldFBlcmNlbnQpIHtcbiAgICAvLyBCYXNpYyBwb2ludCBvZmZzZXRcbiAgICBpZiAodmFsdWVJbmRleCA9PT0gLTEpIHtcbiAgICAgIC8vID4+Pj4gRHJhZ2dpbmcgb24gdGhlIHRyYWNrXG4gICAgICB2YXIgc3RhcnRWYWx1ZSA9IG9yaWdpblZhbHVlc1swXTtcbiAgICAgIHZhciBlbmRWYWx1ZSA9IG9yaWdpblZhbHVlc1tvcmlnaW5WYWx1ZXMubGVuZ3RoIC0gMV07XG4gICAgICB2YXIgbWF4U3RhcnRPZmZzZXQgPSBtaW4gLSBzdGFydFZhbHVlO1xuICAgICAgdmFyIG1heEVuZE9mZnNldCA9IG1heCAtIGVuZFZhbHVlO1xuICAgICAgLy8gR2V0IHZhbGlkIG9mZnNldFxuICAgICAgdmFyIG9mZnNldCA9IG9mZnNldFBlcmNlbnQgKiAobWF4IC0gbWluKTtcbiAgICAgIG9mZnNldCA9IE1hdGgubWF4KG9mZnNldCwgbWF4U3RhcnRPZmZzZXQpO1xuICAgICAgb2Zmc2V0ID0gTWF0aC5taW4ob2Zmc2V0LCBtYXhFbmRPZmZzZXQpO1xuICAgICAgLy8gVXNlIGZpcnN0IHZhbHVlIHRvIHJldmVydCBiYWNrIG9mIHZhbGlkIG9mZnNldCAobGlrZSBzdGVwcyBtYXJrcylcbiAgICAgIHZhciBmb3JtYXRTdGFydFZhbHVlID0gZm9ybWF0VmFsdWUoc3RhcnRWYWx1ZSArIG9mZnNldCk7XG4gICAgICBvZmZzZXQgPSBmb3JtYXRTdGFydFZhbHVlIC0gc3RhcnRWYWx1ZTtcbiAgICAgIHZhciBjbG9uZUNhY2hlVmFsdWVzID0gb3JpZ2luVmFsdWVzLm1hcChmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIHJldHVybiB2YWwgKyBvZmZzZXQ7XG4gICAgICB9KTtcbiAgICAgIGZsdXNoVmFsdWVzKGNsb25lQ2FjaGVWYWx1ZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyA+Pj4+IERyYWdnaW5nIG9uIHRoZSBoYW5kbGVcbiAgICAgIHZhciBvZmZzZXREaXN0ID0gKG1heCAtIG1pbikgKiBvZmZzZXRQZXJjZW50O1xuICAgICAgLy8gQWx3YXlzIHN0YXJ0IHdpdGggdGhlIHZhbHVlSW5kZXggb3JpZ2luIHZhbHVlXG4gICAgICB2YXIgY2xvbmVWYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkoY2FjaGVWYWx1ZXMpO1xuICAgICAgY2xvbmVWYWx1ZXNbdmFsdWVJbmRleF0gPSBvcmlnaW5WYWx1ZXNbdmFsdWVJbmRleF07XG4gICAgICB2YXIgbmV4dCA9IG9mZnNldFZhbHVlcyhjbG9uZVZhbHVlcywgb2Zmc2V0RGlzdCwgdmFsdWVJbmRleCwgJ2Rpc3QnKTtcbiAgICAgIGZsdXNoVmFsdWVzKG5leHQudmFsdWVzLCBuZXh0LnZhbHVlKTtcbiAgICB9XG4gIH07XG4gIC8vIFJlc29sdmUgY2xvc3VyZVxuICB2YXIgdXBkYXRlQ2FjaGVWYWx1ZVJlZiA9IFJlYWN0LnVzZVJlZih1cGRhdGVDYWNoZVZhbHVlKTtcbiAgdXBkYXRlQ2FjaGVWYWx1ZVJlZi5jdXJyZW50ID0gdXBkYXRlQ2FjaGVWYWx1ZTtcbiAgdmFyIG9uU3RhcnRNb3ZlID0gZnVuY3Rpb24gb25TdGFydE1vdmUoZSwgdmFsdWVJbmRleCkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdmFyIG9yaWdpblZhbHVlID0gcmF3VmFsdWVzW3ZhbHVlSW5kZXhdO1xuICAgIHNldERyYWdnaW5nSW5kZXgodmFsdWVJbmRleCk7XG4gICAgc2V0RHJhZ2dpbmdWYWx1ZShvcmlnaW5WYWx1ZSk7XG4gICAgc2V0T3JpZ2luVmFsdWVzKHJhd1ZhbHVlcyk7XG4gICAgdmFyIF9nZXRQb3NpdGlvbiA9IGdldFBvc2l0aW9uKGUpLFxuICAgICAgc3RhcnRYID0gX2dldFBvc2l0aW9uLnBhZ2VYLFxuICAgICAgc3RhcnRZID0gX2dldFBvc2l0aW9uLnBhZ2VZO1xuICAgIC8vIE1vdmluZ1xuICAgIHZhciBvbk1vdXNlTW92ZSA9IGZ1bmN0aW9uIG9uTW91c2VNb3ZlKGV2ZW50KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdmFyIF9nZXRQb3NpdGlvbjIgPSBnZXRQb3NpdGlvbihldmVudCksXG4gICAgICAgIG1vdmVYID0gX2dldFBvc2l0aW9uMi5wYWdlWCxcbiAgICAgICAgbW92ZVkgPSBfZ2V0UG9zaXRpb24yLnBhZ2VZO1xuICAgICAgdmFyIG9mZnNldFggPSBtb3ZlWCAtIHN0YXJ0WDtcbiAgICAgIHZhciBvZmZzZXRZID0gbW92ZVkgLSBzdGFydFk7XG4gICAgICB2YXIgX2NvbnRhaW5lclJlZiRjdXJyZW50ID0gY29udGFpbmVyUmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICAgIHdpZHRoID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LndpZHRoLFxuICAgICAgICBoZWlnaHQgPSBfY29udGFpbmVyUmVmJGN1cnJlbnQuaGVpZ2h0O1xuICAgICAgdmFyIG9mZlNldFBlcmNlbnQ7XG4gICAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgICBjYXNlICdidHQnOlxuICAgICAgICAgIG9mZlNldFBlcmNlbnQgPSAtb2Zmc2V0WSAvIGhlaWdodDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndHRiJzpcbiAgICAgICAgICBvZmZTZXRQZXJjZW50ID0gb2Zmc2V0WSAvIGhlaWdodDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAncnRsJzpcbiAgICAgICAgICBvZmZTZXRQZXJjZW50ID0gLW9mZnNldFggLyB3aWR0aDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBvZmZTZXRQZXJjZW50ID0gb2Zmc2V0WCAvIHdpZHRoO1xuICAgICAgfVxuICAgICAgdXBkYXRlQ2FjaGVWYWx1ZVJlZi5jdXJyZW50KHZhbHVlSW5kZXgsIG9mZlNldFBlcmNlbnQpO1xuICAgIH07XG4gICAgLy8gRW5kXG4gICAgdmFyIG9uTW91c2VVcCA9IGZ1bmN0aW9uIG9uTW91c2VVcChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvbk1vdXNlVXApO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCBvbk1vdXNlVXApO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgICAgbW91c2VNb3ZlRXZlbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBtb3VzZVVwRXZlbnRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBzZXREcmFnZ2luZ0luZGV4KC0xKTtcbiAgICAgIGZpbmlzaENoYW5nZSgpO1xuICAgIH07XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG9uTW91c2VVcCk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgb25Nb3VzZVVwKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBvbk1vdXNlTW92ZSk7XG4gICAgbW91c2VNb3ZlRXZlbnRSZWYuY3VycmVudCA9IG9uTW91c2VNb3ZlO1xuICAgIG1vdXNlVXBFdmVudFJlZi5jdXJyZW50ID0gb25Nb3VzZVVwO1xuICB9O1xuICAvLyBPbmx5IHJldHVybiBjYWNoZSB2YWx1ZSB3aGVuIGl0IG1hcHBpbmcgd2l0aCByYXdWYWx1ZXNcbiAgdmFyIHJldHVyblZhbHVlcyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHZhciBzb3VyY2VWYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkocmF3VmFsdWVzKS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gYSAtIGI7XG4gICAgfSk7XG4gICAgdmFyIHRhcmdldFZhbHVlcyA9IF90b0NvbnN1bWFibGVBcnJheShjYWNoZVZhbHVlcykuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIHJldHVybiBzb3VyY2VWYWx1ZXMuZXZlcnkoZnVuY3Rpb24gKHZhbCwgaW5kZXgpIHtcbiAgICAgIHJldHVybiB2YWwgPT09IHRhcmdldFZhbHVlc1tpbmRleF07XG4gICAgfSkgPyBjYWNoZVZhbHVlcyA6IHJhd1ZhbHVlcztcbiAgfSwgW3Jhd1ZhbHVlcywgY2FjaGVWYWx1ZXNdKTtcbiAgcmV0dXJuIFtkcmFnZ2luZ0luZGV4LCBkcmFnZ2luZ1ZhbHVlLCByZXR1cm5WYWx1ZXMsIG9uU3RhcnRNb3ZlXTtcbn0iLCJpbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgU2xpZGVyQ29udGV4dCBmcm9tICcuLi9jb250ZXh0JztcbmltcG9ydCB7IGdldE9mZnNldCB9IGZyb20gJy4uL3V0aWwnO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVHJhY2socHJvcHMpIHtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIHN0YXJ0ID0gcHJvcHMuc3RhcnQsXG4gICAgZW5kID0gcHJvcHMuZW5kLFxuICAgIGluZGV4ID0gcHJvcHMuaW5kZXgsXG4gICAgb25TdGFydE1vdmUgPSBwcm9wcy5vblN0YXJ0TW92ZTtcbiAgdmFyIF9SZWFjdCR1c2VDb250ZXh0ID0gUmVhY3QudXNlQ29udGV4dChTbGlkZXJDb250ZXh0KSxcbiAgICBkaXJlY3Rpb24gPSBfUmVhY3QkdXNlQ29udGV4dC5kaXJlY3Rpb24sXG4gICAgbWluID0gX1JlYWN0JHVzZUNvbnRleHQubWluLFxuICAgIG1heCA9IF9SZWFjdCR1c2VDb250ZXh0Lm1heCxcbiAgICBkaXNhYmxlZCA9IF9SZWFjdCR1c2VDb250ZXh0LmRpc2FibGVkLFxuICAgIHJhbmdlID0gX1JlYWN0JHVzZUNvbnRleHQucmFuZ2U7XG4gIHZhciB0cmFja1ByZWZpeENscyA9IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItdHJhY2tcIik7XG4gIHZhciBvZmZzZXRTdGFydCA9IGdldE9mZnNldChzdGFydCwgbWluLCBtYXgpO1xuICB2YXIgb2Zmc2V0RW5kID0gZ2V0T2Zmc2V0KGVuZCwgbWluLCBtYXgpO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09IEV2ZW50cyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBvbkludGVybmFsU3RhcnRNb3ZlID0gZnVuY3Rpb24gb25JbnRlcm5hbFN0YXJ0TW92ZShlKSB7XG4gICAgaWYgKCFkaXNhYmxlZCAmJiBvblN0YXJ0TW92ZSkge1xuICAgICAgb25TdGFydE1vdmUoZSwgLTEpO1xuICAgIH1cbiAgfTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgcG9zaXRpb25TdHlsZSA9IHt9O1xuICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgIGNhc2UgJ3J0bCc6XG4gICAgICBwb3NpdGlvblN0eWxlLnJpZ2h0ID0gXCJcIi5jb25jYXQob2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUud2lkdGggPSBcIlwiLmNvbmNhdChvZmZzZXRFbmQgKiAxMDAgLSBvZmZzZXRTdGFydCAqIDEwMCwgXCIlXCIpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYnR0JzpcbiAgICAgIHBvc2l0aW9uU3R5bGUuYm90dG9tID0gXCJcIi5jb25jYXQob2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUuaGVpZ2h0ID0gXCJcIi5jb25jYXQob2Zmc2V0RW5kICogMTAwIC0gb2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3R0Yic6XG4gICAgICBwb3NpdGlvblN0eWxlLnRvcCA9IFwiXCIuY29uY2F0KG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBwb3NpdGlvblN0eWxlLmhlaWdodCA9IFwiXCIuY29uY2F0KG9mZnNldEVuZCAqIDEwMCAtIG9mZnNldFN0YXJ0ICogMTAwLCBcIiVcIik7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgcG9zaXRpb25TdHlsZS5sZWZ0ID0gXCJcIi5jb25jYXQob2Zmc2V0U3RhcnQgKiAxMDAsIFwiJVwiKTtcbiAgICAgIHBvc2l0aW9uU3R5bGUud2lkdGggPSBcIlwiLmNvbmNhdChvZmZzZXRFbmQgKiAxMDAgLSBvZmZzZXRTdGFydCAqIDEwMCwgXCIlXCIpO1xuICB9XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKHRyYWNrUHJlZml4Q2xzLCByYW5nZSAmJiBcIlwiLmNvbmNhdCh0cmFja1ByZWZpeENscywgXCItXCIpLmNvbmNhdChpbmRleCArIDEpKSxcbiAgICBzdHlsZTogX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBwb3NpdGlvblN0eWxlKSwgc3R5bGUpLFxuICAgIG9uTW91c2VEb3duOiBvbkludGVybmFsU3RhcnRNb3ZlLFxuICAgIG9uVG91Y2hTdGFydDogb25JbnRlcm5hbFN0YXJ0TW92ZVxuICB9KTtcbn0iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU2xpZGVyQ29udGV4dCBmcm9tICcuLi9jb250ZXh0JztcbmltcG9ydCBUcmFjayBmcm9tICcuL1RyYWNrJztcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSAnLi4vdXRpbCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUcmFja3MocHJvcHMpIHtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIHZhbHVlcyA9IHByb3BzLnZhbHVlcyxcbiAgICBzdGFydFBvaW50ID0gcHJvcHMuc3RhcnRQb2ludCxcbiAgICBvblN0YXJ0TW92ZSA9IHByb3BzLm9uU3RhcnRNb3ZlO1xuICB2YXIgX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KFNsaWRlckNvbnRleHQpLFxuICAgIGluY2x1ZGVkID0gX1JlYWN0JHVzZUNvbnRleHQuaW5jbHVkZWQsXG4gICAgcmFuZ2UgPSBfUmVhY3QkdXNlQ29udGV4dC5yYW5nZSxcbiAgICBtaW4gPSBfUmVhY3QkdXNlQ29udGV4dC5taW47XG4gIHZhciB0cmFja0xpc3QgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAvLyBudWxsIHZhbHVlIGRvIG5vdCBoYXZlIHRyYWNrXG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG4gICAgICB2YXIgc3RhcnRWYWx1ZSA9IHN0YXJ0UG9pbnQgIT09IG51bGwgJiYgc3RhcnRQb2ludCAhPT0gdm9pZCAwID8gc3RhcnRQb2ludCA6IG1pbjtcbiAgICAgIHZhciBlbmRWYWx1ZSA9IHZhbHVlc1swXTtcbiAgICAgIHJldHVybiBbe1xuICAgICAgICBzdGFydDogTWF0aC5taW4oc3RhcnRWYWx1ZSwgZW5kVmFsdWUpLFxuICAgICAgICBlbmQ6IE1hdGgubWF4KHN0YXJ0VmFsdWUsIGVuZFZhbHVlKVxuICAgICAgfV07XG4gICAgfVxuICAgIC8vIE11bHRpcGxlXG4gICAgdmFyIGxpc3QgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGggLSAxOyBpICs9IDEpIHtcbiAgICAgIGxpc3QucHVzaCh7XG4gICAgICAgIHN0YXJ0OiB2YWx1ZXNbaV0sXG4gICAgICAgIGVuZDogdmFsdWVzW2kgKyAxXVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBsaXN0O1xuICB9LCBbdmFsdWVzLCByYW5nZSwgc3RhcnRQb2ludCwgbWluXSk7XG4gIHJldHVybiBpbmNsdWRlZCA/IHRyYWNrTGlzdC5tYXAoZnVuY3Rpb24gKF9yZWYsIGluZGV4KSB7XG4gICAgdmFyIHN0YXJ0ID0gX3JlZi5zdGFydCxcbiAgICAgIGVuZCA9IF9yZWYuZW5kO1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUcmFjaywge1xuICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICBzdHlsZTogZ2V0SW5kZXgoc3R5bGUsIGluZGV4KSxcbiAgICAgIHN0YXJ0OiBzdGFydCxcbiAgICAgIGVuZDogZW5kLFxuICAgICAga2V5OiBpbmRleCxcbiAgICAgIG9uU3RhcnRNb3ZlOiBvblN0YXJ0TW92ZVxuICAgIH0pO1xuICB9KSA6IG51bGw7XG59IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCB7IGdldERpcmVjdGlvblN0eWxlIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgU2xpZGVyQ29udGV4dCBmcm9tICcuLi9jb250ZXh0JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1hcmsocHJvcHMpIHtcbiAgdmFyIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgdmFsdWUgPSBwcm9wcy52YWx1ZSxcbiAgICBfb25DbGljayA9IHByb3BzLm9uQ2xpY2s7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoU2xpZGVyQ29udGV4dCksXG4gICAgbWluID0gX1JlYWN0JHVzZUNvbnRleHQubWluLFxuICAgIG1heCA9IF9SZWFjdCR1c2VDb250ZXh0Lm1heCxcbiAgICBkaXJlY3Rpb24gPSBfUmVhY3QkdXNlQ29udGV4dC5kaXJlY3Rpb24sXG4gICAgaW5jbHVkZWRTdGFydCA9IF9SZWFjdCR1c2VDb250ZXh0LmluY2x1ZGVkU3RhcnQsXG4gICAgaW5jbHVkZWRFbmQgPSBfUmVhY3QkdXNlQ29udGV4dC5pbmNsdWRlZEVuZCxcbiAgICBpbmNsdWRlZCA9IF9SZWFjdCR1c2VDb250ZXh0LmluY2x1ZGVkO1xuICB2YXIgdGV4dENscyA9IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItdGV4dFwiKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBPZmZzZXQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgcG9zaXRpb25TdHlsZSA9IGdldERpcmVjdGlvblN0eWxlKGRpcmVjdGlvbiwgdmFsdWUsIG1pbiwgbWF4KTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7XG4gICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKHRleHRDbHMsIF9kZWZpbmVQcm9wZXJ0eSh7fSwgXCJcIi5jb25jYXQodGV4dENscywgXCItYWN0aXZlXCIpLCBpbmNsdWRlZCAmJiBpbmNsdWRlZFN0YXJ0IDw9IHZhbHVlICYmIHZhbHVlIDw9IGluY2x1ZGVkRW5kKSksXG4gICAgc3R5bGU6IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgcG9zaXRpb25TdHlsZSksIHN0eWxlKSxcbiAgICBvbk1vdXNlRG93bjogZnVuY3Rpb24gb25Nb3VzZURvd24oZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9LFxuICAgIG9uQ2xpY2s6IGZ1bmN0aW9uIG9uQ2xpY2soKSB7XG4gICAgICBfb25DbGljayh2YWx1ZSk7XG4gICAgfVxuICB9LCBjaGlsZHJlbik7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IE1hcmsgZnJvbSAnLi9NYXJrJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1hcmtzKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgbWFya3MgPSBwcm9wcy5tYXJrcyxcbiAgICBvbkNsaWNrID0gcHJvcHMub25DbGljaztcbiAgdmFyIG1hcmtQcmVmaXhDbHMgPSBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLW1hcmtcIik7XG4gIC8vIE5vdCByZW5kZXIgbWFyayBpZiBlbXB0eVxuICBpZiAoIW1hcmtzLmxlbmd0aCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgY2xhc3NOYW1lOiBtYXJrUHJlZml4Q2xzXG4gIH0sIG1hcmtzLm1hcChmdW5jdGlvbiAoX3JlZikge1xuICAgIHZhciB2YWx1ZSA9IF9yZWYudmFsdWUsXG4gICAgICBzdHlsZSA9IF9yZWYuc3R5bGUsXG4gICAgICBsYWJlbCA9IF9yZWYubGFiZWw7XG4gICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1hcmssIHtcbiAgICAgIGtleTogdmFsdWUsXG4gICAgICBwcmVmaXhDbHM6IG1hcmtQcmVmaXhDbHMsXG4gICAgICBzdHlsZTogc3R5bGUsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBvbkNsaWNrOiBvbkNsaWNrXG4gICAgfSwgbGFiZWwpO1xuICB9KSk7XG59IiwiaW1wb3J0IF9kZWZpbmVQcm9wZXJ0eSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZGVmaW5lUHJvcGVydHlcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tICdjbGFzc25hbWVzJztcbmltcG9ydCB7IGdldERpcmVjdGlvblN0eWxlIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgU2xpZGVyQ29udGV4dCBmcm9tICcuLi9jb250ZXh0JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERvdChwcm9wcykge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIHZhbHVlID0gcHJvcHMudmFsdWUsXG4gICAgc3R5bGUgPSBwcm9wcy5zdHlsZSxcbiAgICBhY3RpdmVTdHlsZSA9IHByb3BzLmFjdGl2ZVN0eWxlO1xuICB2YXIgX1JlYWN0JHVzZUNvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KFNsaWRlckNvbnRleHQpLFxuICAgIG1pbiA9IF9SZWFjdCR1c2VDb250ZXh0Lm1pbixcbiAgICBtYXggPSBfUmVhY3QkdXNlQ29udGV4dC5tYXgsXG4gICAgZGlyZWN0aW9uID0gX1JlYWN0JHVzZUNvbnRleHQuZGlyZWN0aW9uLFxuICAgIGluY2x1ZGVkID0gX1JlYWN0JHVzZUNvbnRleHQuaW5jbHVkZWQsXG4gICAgaW5jbHVkZWRTdGFydCA9IF9SZWFjdCR1c2VDb250ZXh0LmluY2x1ZGVkU3RhcnQsXG4gICAgaW5jbHVkZWRFbmQgPSBfUmVhY3QkdXNlQ29udGV4dC5pbmNsdWRlZEVuZDtcbiAgdmFyIGRvdENsYXNzTmFtZSA9IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItZG90XCIpO1xuICB2YXIgYWN0aXZlID0gaW5jbHVkZWQgJiYgaW5jbHVkZWRTdGFydCA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSBpbmNsdWRlZEVuZDtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBPZmZzZXQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWVyZ2VkU3R5bGUgPSBfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGdldERpcmVjdGlvblN0eWxlKGRpcmVjdGlvbiwgdmFsdWUsIG1pbiwgbWF4KSksIHR5cGVvZiBzdHlsZSA9PT0gJ2Z1bmN0aW9uJyA/IHN0eWxlKHZhbHVlKSA6IHN0eWxlKTtcbiAgaWYgKGFjdGl2ZSkge1xuICAgIG1lcmdlZFN0eWxlID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBtZXJnZWRTdHlsZSksIHR5cGVvZiBhY3RpdmVTdHlsZSA9PT0gJ2Z1bmN0aW9uJyA/IGFjdGl2ZVN0eWxlKHZhbHVlKSA6IGFjdGl2ZVN0eWxlKTtcbiAgfVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIHtcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMoZG90Q2xhc3NOYW1lLCBfZGVmaW5lUHJvcGVydHkoe30sIFwiXCIuY29uY2F0KGRvdENsYXNzTmFtZSwgXCItYWN0aXZlXCIpLCBhY3RpdmUpKSxcbiAgICBzdHlsZTogbWVyZ2VkU3R5bGVcbiAgfSk7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi4vY29udGV4dCc7XG5pbXBvcnQgRG90IGZyb20gJy4vRG90JztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFN0ZXBzKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgbWFya3MgPSBwcm9wcy5tYXJrcyxcbiAgICBkb3RzID0gcHJvcHMuZG90cyxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIGFjdGl2ZVN0eWxlID0gcHJvcHMuYWN0aXZlU3R5bGU7XG4gIHZhciBfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoU2xpZGVyQ29udGV4dCksXG4gICAgbWluID0gX1JlYWN0JHVzZUNvbnRleHQubWluLFxuICAgIG1heCA9IF9SZWFjdCR1c2VDb250ZXh0Lm1heCxcbiAgICBzdGVwID0gX1JlYWN0JHVzZUNvbnRleHQuc3RlcDtcbiAgdmFyIHN0ZXBEb3RzID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGRvdFNldCA9IG5ldyBTZXQoKTtcbiAgICAvLyBBZGQgbWFya3NcbiAgICBtYXJrcy5mb3JFYWNoKGZ1bmN0aW9uIChtYXJrKSB7XG4gICAgICBkb3RTZXQuYWRkKG1hcmsudmFsdWUpO1xuICAgIH0pO1xuICAgIC8vIEZpbGwgZG90c1xuICAgIGlmIChkb3RzICYmIHN0ZXAgIT09IG51bGwpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gbWluO1xuICAgICAgd2hpbGUgKGN1cnJlbnQgPD0gbWF4KSB7XG4gICAgICAgIGRvdFNldC5hZGQoY3VycmVudCk7XG4gICAgICAgIGN1cnJlbnQgKz0gc3RlcDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIEFycmF5LmZyb20oZG90U2V0KTtcbiAgfSwgW21pbiwgbWF4LCBzdGVwLCBkb3RzLCBtYXJrc10pO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1zdGVwXCIpXG4gIH0sIHN0ZXBEb3RzLm1hcChmdW5jdGlvbiAoZG90VmFsdWUpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG90LCB7XG4gICAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICAgIGtleTogZG90VmFsdWUsXG4gICAgICB2YWx1ZTogZG90VmFsdWUsXG4gICAgICBzdHlsZTogc3R5bGUsXG4gICAgICBhY3RpdmVTdHlsZTogYWN0aXZlU3R5bGVcbiAgICB9KTtcbiAgfSkpO1xufSIsImltcG9ydCBfdG9Db25zdW1hYmxlQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3RvQ29uc3VtYWJsZUFycmF5XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VPZmZzZXQobWluLCBtYXgsIHN0ZXAsIG1hcmtMaXN0LCBhbGxvd0Nyb3NzLCBwdXNoYWJsZSkge1xuICB2YXIgZm9ybWF0UmFuZ2VWYWx1ZSA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uICh2YWwpIHtcbiAgICB2YXIgZm9ybWF0TmV4dFZhbHVlID0gaXNGaW5pdGUodmFsKSA/IHZhbCA6IG1pbjtcbiAgICBmb3JtYXROZXh0VmFsdWUgPSBNYXRoLm1pbihtYXgsIHZhbCk7XG4gICAgZm9ybWF0TmV4dFZhbHVlID0gTWF0aC5tYXgobWluLCBmb3JtYXROZXh0VmFsdWUpO1xuICAgIHJldHVybiBmb3JtYXROZXh0VmFsdWU7XG4gIH0sIFttaW4sIG1heF0pO1xuICB2YXIgZm9ybWF0U3RlcFZhbHVlID0gUmVhY3QudXNlQ2FsbGJhY2soZnVuY3Rpb24gKHZhbCkge1xuICAgIGlmIChzdGVwICE9PSBudWxsKSB7XG4gICAgICB2YXIgc3RlcFZhbHVlID0gbWluICsgTWF0aC5yb3VuZCgoZm9ybWF0UmFuZ2VWYWx1ZSh2YWwpIC0gbWluKSAvIHN0ZXApICogc3RlcDtcbiAgICAgIC8vIEN1dCBudW1iZXIgaW4gY2FzZSB0byBiZSBsaWtlIDAuMzAwMDAwMDAwMDAwMDAwMDRcbiAgICAgIHZhciBnZXREZWNpbWFsID0gZnVuY3Rpb24gZ2V0RGVjaW1hbChudW0pIHtcbiAgICAgICAgcmV0dXJuIChTdHJpbmcobnVtKS5zcGxpdCgnLicpWzFdIHx8ICcnKS5sZW5ndGg7XG4gICAgICB9O1xuICAgICAgdmFyIG1heERlY2ltYWwgPSBNYXRoLm1heChnZXREZWNpbWFsKHN0ZXApLCBnZXREZWNpbWFsKG1heCksIGdldERlY2ltYWwobWluKSk7XG4gICAgICB2YXIgZml4ZWRWYWx1ZSA9IE51bWJlcihzdGVwVmFsdWUudG9GaXhlZChtYXhEZWNpbWFsKSk7XG4gICAgICByZXR1cm4gbWluIDw9IGZpeGVkVmFsdWUgJiYgZml4ZWRWYWx1ZSA8PSBtYXggPyBmaXhlZFZhbHVlIDogbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sIFtzdGVwLCBtaW4sIG1heCwgZm9ybWF0UmFuZ2VWYWx1ZV0pO1xuICB2YXIgZm9ybWF0VmFsdWUgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAodmFsKSB7XG4gICAgdmFyIGZvcm1hdE5leHRWYWx1ZSA9IGZvcm1hdFJhbmdlVmFsdWUodmFsKTtcbiAgICAvLyBMaXN0IGFsaWduIHZhbHVlc1xuICAgIHZhciBhbGlnblZhbHVlcyA9IG1hcmtMaXN0Lm1hcChmdW5jdGlvbiAobWFyaykge1xuICAgICAgcmV0dXJuIG1hcmsudmFsdWU7XG4gICAgfSk7XG4gICAgaWYgKHN0ZXAgIT09IG51bGwpIHtcbiAgICAgIGFsaWduVmFsdWVzLnB1c2goZm9ybWF0U3RlcFZhbHVlKHZhbCkpO1xuICAgIH1cbiAgICAvLyBtaW4gJiBtYXhcbiAgICBhbGlnblZhbHVlcy5wdXNoKG1pbiwgbWF4KTtcbiAgICAvLyBBbGlnbiB3aXRoIG1hcmtzXG4gICAgdmFyIGNsb3NlVmFsdWUgPSBhbGlnblZhbHVlc1swXTtcbiAgICB2YXIgY2xvc2VEaXN0ID0gbWF4IC0gbWluO1xuICAgIGFsaWduVmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKGFsaWduVmFsdWUpIHtcbiAgICAgIHZhciBkaXN0ID0gTWF0aC5hYnMoZm9ybWF0TmV4dFZhbHVlIC0gYWxpZ25WYWx1ZSk7XG4gICAgICBpZiAoZGlzdCA8PSBjbG9zZURpc3QpIHtcbiAgICAgICAgY2xvc2VWYWx1ZSA9IGFsaWduVmFsdWU7XG4gICAgICAgIGNsb3NlRGlzdCA9IGRpc3Q7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNsb3NlVmFsdWU7XG4gIH0sIFttaW4sIG1heCwgbWFya0xpc3QsIHN0ZXAsIGZvcm1hdFJhbmdlVmFsdWUsIGZvcm1hdFN0ZXBWYWx1ZV0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBPZmZzZXQgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gU2luZ2xlIFZhbHVlXG4gIHZhciBvZmZzZXRWYWx1ZSA9IGZ1bmN0aW9uIG9mZnNldFZhbHVlKHZhbHVlcywgb2Zmc2V0LCB2YWx1ZUluZGV4KSB7XG4gICAgdmFyIG1vZGUgPSBhcmd1bWVudHMubGVuZ3RoID4gMyAmJiBhcmd1bWVudHNbM10gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1szXSA6ICd1bml0JztcbiAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHZhciBuZXh0VmFsdWU7XG4gICAgICB2YXIgb3JpZ2luVmFsdWUgPSB2YWx1ZXNbdmFsdWVJbmRleF07XG4gICAgICAvLyBPbmx5IHVzZWQgZm9yIGBkaXN0YCBtb2RlXG4gICAgICB2YXIgdGFyZ2V0RGlzdFZhbHVlID0gb3JpZ2luVmFsdWUgKyBvZmZzZXQ7XG4gICAgICAvLyBDb21wYXJlIG5leHQgc3RlcCB2YWx1ZSAmIG1hcmsgdmFsdWUgd2hpY2ggaXMgYmVzdCBtYXRjaFxuICAgICAgdmFyIHBvdGVudGlhbFZhbHVlcyA9IFtdO1xuICAgICAgbWFya0xpc3QuZm9yRWFjaChmdW5jdGlvbiAobWFyaykge1xuICAgICAgICBwb3RlbnRpYWxWYWx1ZXMucHVzaChtYXJrLnZhbHVlKTtcbiAgICAgIH0pO1xuICAgICAgLy8gTWluICYgTWF4XG4gICAgICBwb3RlbnRpYWxWYWx1ZXMucHVzaChtaW4sIG1heCk7XG4gICAgICAvLyBJbiBjYXNlIG9yaWdpbiB2YWx1ZSBpcyBhbGlnbiB3aXRoIG1hcmsgYnV0IG5vdCB3aXRoIHN0ZXBcbiAgICAgIHBvdGVudGlhbFZhbHVlcy5wdXNoKGZvcm1hdFN0ZXBWYWx1ZShvcmlnaW5WYWx1ZSkpO1xuICAgICAgLy8gUHV0IG9mZnNldCBzdGVwIHZhbHVlIGFsc29cbiAgICAgIHZhciBzaWduID0gb2Zmc2V0ID4gMCA/IDEgOiAtMTtcbiAgICAgIGlmIChtb2RlID09PSAndW5pdCcpIHtcbiAgICAgICAgcG90ZW50aWFsVmFsdWVzLnB1c2goZm9ybWF0U3RlcFZhbHVlKG9yaWdpblZhbHVlICsgc2lnbiAqIHN0ZXApKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvdGVudGlhbFZhbHVlcy5wdXNoKGZvcm1hdFN0ZXBWYWx1ZSh0YXJnZXREaXN0VmFsdWUpKTtcbiAgICAgIH1cbiAgICAgIC8vIEZpbmQgY2xvc2Ugb25lXG4gICAgICBwb3RlbnRpYWxWYWx1ZXMgPSBwb3RlbnRpYWxWYWx1ZXMuZmlsdGVyKGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgcmV0dXJuIHZhbCAhPT0gbnVsbDtcbiAgICAgIH0pXG4gICAgICAvLyBSZW1vdmUgcmV2ZXJzZSB2YWx1ZVxuICAgICAgLmZpbHRlcihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgIHJldHVybiBvZmZzZXQgPCAwID8gdmFsIDw9IG9yaWdpblZhbHVlIDogdmFsID49IG9yaWdpblZhbHVlO1xuICAgICAgfSk7XG4gICAgICBpZiAobW9kZSA9PT0gJ3VuaXQnKSB7XG4gICAgICAgIC8vIGB1bml0YCBtb2RlIGNhbiBub3QgY29udGFpbiBpdHNlbGZcbiAgICAgICAgcG90ZW50aWFsVmFsdWVzID0gcG90ZW50aWFsVmFsdWVzLmZpbHRlcihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbCAhPT0gb3JpZ2luVmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdmFyIGNvbXBhcmVWYWx1ZSA9IG1vZGUgPT09ICd1bml0JyA/IG9yaWdpblZhbHVlIDogdGFyZ2V0RGlzdFZhbHVlO1xuICAgICAgbmV4dFZhbHVlID0gcG90ZW50aWFsVmFsdWVzWzBdO1xuICAgICAgdmFyIHZhbHVlRGlzdCA9IE1hdGguYWJzKG5leHRWYWx1ZSAtIGNvbXBhcmVWYWx1ZSk7XG4gICAgICBwb3RlbnRpYWxWYWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAocG90ZW50aWFsVmFsdWUpIHtcbiAgICAgICAgdmFyIGRpc3QgPSBNYXRoLmFicyhwb3RlbnRpYWxWYWx1ZSAtIGNvbXBhcmVWYWx1ZSk7XG4gICAgICAgIGlmIChkaXN0IDwgdmFsdWVEaXN0KSB7XG4gICAgICAgICAgbmV4dFZhbHVlID0gcG90ZW50aWFsVmFsdWU7XG4gICAgICAgICAgdmFsdWVEaXN0ID0gZGlzdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBPdXQgb2YgcmFuZ2Ugd2lsbCBiYWNrIHRvIHJhbmdlXG4gICAgICBpZiAobmV4dFZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIG9mZnNldCA8IDAgPyBtaW4gOiBtYXg7XG4gICAgICB9XG4gICAgICAvLyBgZGlzdGAgbW9kZVxuICAgICAgaWYgKG1vZGUgPT09ICdkaXN0Jykge1xuICAgICAgICByZXR1cm4gbmV4dFZhbHVlO1xuICAgICAgfVxuICAgICAgLy8gYHVuaXRgIG1vZGUgbWF5IG5lZWQgYW5vdGhlciByb3VuZFxuICAgICAgaWYgKE1hdGguYWJzKG9mZnNldCkgPiAxKSB7XG4gICAgICAgIHZhciBjbG9uZVZhbHVlcyA9IF90b0NvbnN1bWFibGVBcnJheSh2YWx1ZXMpO1xuICAgICAgICBjbG9uZVZhbHVlc1t2YWx1ZUluZGV4XSA9IG5leHRWYWx1ZTtcbiAgICAgICAgcmV0dXJuIG9mZnNldFZhbHVlKGNsb25lVmFsdWVzLCBvZmZzZXQgLSBzaWduLCB2YWx1ZUluZGV4LCBtb2RlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXh0VmFsdWU7XG4gICAgfSBlbHNlIGlmIChvZmZzZXQgPT09ICdtaW4nKSB7XG4gICAgICByZXR1cm4gbWluO1xuICAgIH0gZWxzZSBpZiAob2Zmc2V0ID09PSAnbWF4Jykge1xuICAgICAgcmV0dXJuIG1heDtcbiAgICB9XG4gIH07XG4gIC8qKiBTYW1lIGFzIGBvZmZzZXRWYWx1ZWAgYnV0IHJldHVybiBgY2hhbmdlZGAgbWFyayB0byB0ZWxsIHZhbHVlIGNoYW5nZWQgKi9cbiAgdmFyIG9mZnNldENoYW5nZWRWYWx1ZSA9IGZ1bmN0aW9uIG9mZnNldENoYW5nZWRWYWx1ZSh2YWx1ZXMsIG9mZnNldCwgdmFsdWVJbmRleCkge1xuICAgIHZhciBtb2RlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAndW5pdCc7XG4gICAgdmFyIG9yaWdpblZhbHVlID0gdmFsdWVzW3ZhbHVlSW5kZXhdO1xuICAgIHZhciBuZXh0VmFsdWUgPSBvZmZzZXRWYWx1ZSh2YWx1ZXMsIG9mZnNldCwgdmFsdWVJbmRleCwgbW9kZSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBuZXh0VmFsdWUsXG4gICAgICBjaGFuZ2VkOiBuZXh0VmFsdWUgIT09IG9yaWdpblZhbHVlXG4gICAgfTtcbiAgfTtcbiAgdmFyIG5lZWRQdXNoID0gZnVuY3Rpb24gbmVlZFB1c2goZGlzdCkge1xuICAgIHJldHVybiBwdXNoYWJsZSA9PT0gbnVsbCAmJiBkaXN0ID09PSAwIHx8IHR5cGVvZiBwdXNoYWJsZSA9PT0gJ251bWJlcicgJiYgZGlzdCA8IHB1c2hhYmxlO1xuICB9O1xuICAvLyBWYWx1ZXNcbiAgdmFyIG9mZnNldFZhbHVlcyA9IGZ1bmN0aW9uIG9mZnNldFZhbHVlcyh2YWx1ZXMsIG9mZnNldCwgdmFsdWVJbmRleCkge1xuICAgIHZhciBtb2RlID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiAndW5pdCc7XG4gICAgdmFyIG5leHRWYWx1ZXMgPSB2YWx1ZXMubWFwKGZvcm1hdFZhbHVlKTtcbiAgICB2YXIgb3JpZ2luVmFsdWUgPSBuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdO1xuICAgIHZhciBuZXh0VmFsdWUgPSBvZmZzZXRWYWx1ZShuZXh0VmFsdWVzLCBvZmZzZXQsIHZhbHVlSW5kZXgsIG1vZGUpO1xuICAgIG5leHRWYWx1ZXNbdmFsdWVJbmRleF0gPSBuZXh0VmFsdWU7XG4gICAgaWYgKGFsbG93Q3Jvc3MgPT09IGZhbHNlKSB7XG4gICAgICAvLyA+Pj4+PiBBbGxvdyBDcm9zc1xuICAgICAgdmFyIHB1c2hOdW0gPSBwdXNoYWJsZSB8fCAwO1xuICAgICAgLy8gPT09PT09PT09PT09IEFsbG93Q3Jvc3MgPT09PT09PT09PT09PT09XG4gICAgICBpZiAodmFsdWVJbmRleCA+IDAgJiYgbmV4dFZhbHVlc1t2YWx1ZUluZGV4IC0gMV0gIT09IG9yaWdpblZhbHVlKSB7XG4gICAgICAgIG5leHRWYWx1ZXNbdmFsdWVJbmRleF0gPSBNYXRoLm1heChuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdLCBuZXh0VmFsdWVzW3ZhbHVlSW5kZXggLSAxXSArIHB1c2hOdW0pO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlSW5kZXggPCBuZXh0VmFsdWVzLmxlbmd0aCAtIDEgJiYgbmV4dFZhbHVlc1t2YWx1ZUluZGV4ICsgMV0gIT09IG9yaWdpblZhbHVlKSB7XG4gICAgICAgIG5leHRWYWx1ZXNbdmFsdWVJbmRleF0gPSBNYXRoLm1pbihuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdLCBuZXh0VmFsdWVzW3ZhbHVlSW5kZXggKyAxXSAtIHB1c2hOdW0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHB1c2hhYmxlID09PSAnbnVtYmVyJyB8fCBwdXNoYWJsZSA9PT0gbnVsbCkge1xuICAgICAgLy8gPj4+Pj4gUHVzaGFibGVcbiAgICAgIC8vID09PT09PT09PT09PT09PSBQdXNoID09PT09PT09PT09PT09PT09PVxuICAgICAgLy8gPj4+Pj4+IEJhc2ljIHB1c2hcbiAgICAgIC8vIEVuZCB2YWx1ZXNcbiAgICAgIGZvciAodmFyIGkgPSB2YWx1ZUluZGV4ICsgMTsgaSA8IG5leHRWYWx1ZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdmFyIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB3aGlsZSAobmVlZFB1c2gobmV4dFZhbHVlc1tpXSAtIG5leHRWYWx1ZXNbaSAtIDFdKSAmJiBjaGFuZ2VkKSB7XG4gICAgICAgICAgdmFyIF9vZmZzZXRDaGFuZ2VkVmFsdWUgPSBvZmZzZXRDaGFuZ2VkVmFsdWUobmV4dFZhbHVlcywgMSwgaSk7XG4gICAgICAgICAgbmV4dFZhbHVlc1tpXSA9IF9vZmZzZXRDaGFuZ2VkVmFsdWUudmFsdWU7XG4gICAgICAgICAgY2hhbmdlZCA9IF9vZmZzZXRDaGFuZ2VkVmFsdWUuY2hhbmdlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gU3RhcnQgdmFsdWVzXG4gICAgICBmb3IgKHZhciBfaSA9IHZhbHVlSW5kZXg7IF9pID4gMDsgX2kgLT0gMSkge1xuICAgICAgICB2YXIgX2NoYW5nZWQgPSB0cnVlO1xuICAgICAgICB3aGlsZSAobmVlZFB1c2gobmV4dFZhbHVlc1tfaV0gLSBuZXh0VmFsdWVzW19pIC0gMV0pICYmIF9jaGFuZ2VkKSB7XG4gICAgICAgICAgdmFyIF9vZmZzZXRDaGFuZ2VkVmFsdWUyID0gb2Zmc2V0Q2hhbmdlZFZhbHVlKG5leHRWYWx1ZXMsIC0xLCBfaSAtIDEpO1xuICAgICAgICAgIG5leHRWYWx1ZXNbX2kgLSAxXSA9IF9vZmZzZXRDaGFuZ2VkVmFsdWUyLnZhbHVlO1xuICAgICAgICAgIF9jaGFuZ2VkID0gX29mZnNldENoYW5nZWRWYWx1ZTIuY2hhbmdlZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gPj4+Pj4gUmV2ZXJ0IGJhY2sgdG8gc2FmZSBwdXNoIHJhbmdlXG4gICAgICAvLyBFbmQgdG8gU3RhcnRcbiAgICAgIGZvciAodmFyIF9pMiA9IG5leHRWYWx1ZXMubGVuZ3RoIC0gMTsgX2kyID4gMDsgX2kyIC09IDEpIHtcbiAgICAgICAgdmFyIF9jaGFuZ2VkMiA9IHRydWU7XG4gICAgICAgIHdoaWxlIChuZWVkUHVzaChuZXh0VmFsdWVzW19pMl0gLSBuZXh0VmFsdWVzW19pMiAtIDFdKSAmJiBfY2hhbmdlZDIpIHtcbiAgICAgICAgICB2YXIgX29mZnNldENoYW5nZWRWYWx1ZTMgPSBvZmZzZXRDaGFuZ2VkVmFsdWUobmV4dFZhbHVlcywgLTEsIF9pMiAtIDEpO1xuICAgICAgICAgIG5leHRWYWx1ZXNbX2kyIC0gMV0gPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlMy52YWx1ZTtcbiAgICAgICAgICBfY2hhbmdlZDIgPSBfb2Zmc2V0Q2hhbmdlZFZhbHVlMy5jaGFuZ2VkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBTdGFydCB0byBFbmRcbiAgICAgIGZvciAodmFyIF9pMyA9IDA7IF9pMyA8IG5leHRWYWx1ZXMubGVuZ3RoIC0gMTsgX2kzICs9IDEpIHtcbiAgICAgICAgdmFyIF9jaGFuZ2VkMyA9IHRydWU7XG4gICAgICAgIHdoaWxlIChuZWVkUHVzaChuZXh0VmFsdWVzW19pMyArIDFdIC0gbmV4dFZhbHVlc1tfaTNdKSAmJiBfY2hhbmdlZDMpIHtcbiAgICAgICAgICB2YXIgX29mZnNldENoYW5nZWRWYWx1ZTQgPSBvZmZzZXRDaGFuZ2VkVmFsdWUobmV4dFZhbHVlcywgMSwgX2kzICsgMSk7XG4gICAgICAgICAgbmV4dFZhbHVlc1tfaTMgKyAxXSA9IF9vZmZzZXRDaGFuZ2VkVmFsdWU0LnZhbHVlO1xuICAgICAgICAgIF9jaGFuZ2VkMyA9IF9vZmZzZXRDaGFuZ2VkVmFsdWU0LmNoYW5nZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHZhbHVlOiBuZXh0VmFsdWVzW3ZhbHVlSW5kZXhdLFxuICAgICAgdmFsdWVzOiBuZXh0VmFsdWVzXG4gICAgfTtcbiAgfTtcbiAgcmV0dXJuIFtmb3JtYXRWYWx1ZSwgb2Zmc2V0VmFsdWVzXTtcbn0iLCJpbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xuaW1wb3J0IF90b0NvbnN1bWFibGVBcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXlcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IF90eXBlb2YgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3R5cGVvZlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgaXNFcXVhbCBmcm9tIFwicmMtdXRpbC9lcy9pc0VxdWFsXCI7XG5pbXBvcnQgdXNlTWVyZ2VkU3RhdGUgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlTWVyZ2VkU3RhdGVcIjtcbmltcG9ydCBIYW5kbGVzIGZyb20gJy4vSGFuZGxlcyc7XG5pbXBvcnQgdXNlRHJhZyBmcm9tICcuL2hvb2tzL3VzZURyYWcnO1xuaW1wb3J0IFNsaWRlckNvbnRleHQgZnJvbSAnLi9jb250ZXh0JztcbmltcG9ydCBUcmFja3MgZnJvbSAnLi9UcmFja3MnO1xuaW1wb3J0IE1hcmtzIGZyb20gJy4vTWFya3MnO1xuaW1wb3J0IFN0ZXBzIGZyb20gJy4vU3RlcHMnO1xuaW1wb3J0IHVzZU9mZnNldCBmcm9tICcuL2hvb2tzL3VzZU9mZnNldCc7XG5pbXBvcnQgd2FybmluZyBmcm9tIFwicmMtdXRpbC9lcy93YXJuaW5nXCI7XG52YXIgU2xpZGVyID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgdmFyIF9jbGFzc05hbWVzO1xuICB2YXIgX3Byb3BzJHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBwcmVmaXhDbHMgPSBfcHJvcHMkcHJlZml4Q2xzID09PSB2b2lkIDAgPyAncmMtc2xpZGVyJyA6IF9wcm9wcyRwcmVmaXhDbHMsXG4gICAgY2xhc3NOYW1lID0gcHJvcHMuY2xhc3NOYW1lLFxuICAgIHN0eWxlID0gcHJvcHMuc3R5bGUsXG4gICAgX3Byb3BzJGRpc2FibGVkID0gcHJvcHMuZGlzYWJsZWQsXG4gICAgZGlzYWJsZWQgPSBfcHJvcHMkZGlzYWJsZWQgPT09IHZvaWQgMCA/IGZhbHNlIDogX3Byb3BzJGRpc2FibGVkLFxuICAgIF9wcm9wcyRrZXlib2FyZCA9IHByb3BzLmtleWJvYXJkLFxuICAgIGtleWJvYXJkID0gX3Byb3BzJGtleWJvYXJkID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJGtleWJvYXJkLFxuICAgIGF1dG9Gb2N1cyA9IHByb3BzLmF1dG9Gb2N1cyxcbiAgICBvbkZvY3VzID0gcHJvcHMub25Gb2N1cyxcbiAgICBvbkJsdXIgPSBwcm9wcy5vbkJsdXIsXG4gICAgX3Byb3BzJG1pbiA9IHByb3BzLm1pbixcbiAgICBtaW4gPSBfcHJvcHMkbWluID09PSB2b2lkIDAgPyAwIDogX3Byb3BzJG1pbixcbiAgICBfcHJvcHMkbWF4ID0gcHJvcHMubWF4LFxuICAgIG1heCA9IF9wcm9wcyRtYXggPT09IHZvaWQgMCA/IDEwMCA6IF9wcm9wcyRtYXgsXG4gICAgX3Byb3BzJHN0ZXAgPSBwcm9wcy5zdGVwLFxuICAgIHN0ZXAgPSBfcHJvcHMkc3RlcCA9PT0gdm9pZCAwID8gMSA6IF9wcm9wcyRzdGVwLFxuICAgIHZhbHVlID0gcHJvcHMudmFsdWUsXG4gICAgZGVmYXVsdFZhbHVlID0gcHJvcHMuZGVmYXVsdFZhbHVlLFxuICAgIHJhbmdlID0gcHJvcHMucmFuZ2UsXG4gICAgY291bnQgPSBwcm9wcy5jb3VudCxcbiAgICBvbkNoYW5nZSA9IHByb3BzLm9uQ2hhbmdlLFxuICAgIG9uQmVmb3JlQ2hhbmdlID0gcHJvcHMub25CZWZvcmVDaGFuZ2UsXG4gICAgb25BZnRlckNoYW5nZSA9IHByb3BzLm9uQWZ0ZXJDaGFuZ2UsXG4gICAgX3Byb3BzJGFsbG93Q3Jvc3MgPSBwcm9wcy5hbGxvd0Nyb3NzLFxuICAgIGFsbG93Q3Jvc3MgPSBfcHJvcHMkYWxsb3dDcm9zcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRhbGxvd0Nyb3NzLFxuICAgIF9wcm9wcyRwdXNoYWJsZSA9IHByb3BzLnB1c2hhYmxlLFxuICAgIHB1c2hhYmxlID0gX3Byb3BzJHB1c2hhYmxlID09PSB2b2lkIDAgPyBmYWxzZSA6IF9wcm9wcyRwdXNoYWJsZSxcbiAgICBkcmFnZ2FibGVUcmFjayA9IHByb3BzLmRyYWdnYWJsZVRyYWNrLFxuICAgIHJldmVyc2UgPSBwcm9wcy5yZXZlcnNlLFxuICAgIHZlcnRpY2FsID0gcHJvcHMudmVydGljYWwsXG4gICAgX3Byb3BzJGluY2x1ZGVkID0gcHJvcHMuaW5jbHVkZWQsXG4gICAgaW5jbHVkZWQgPSBfcHJvcHMkaW5jbHVkZWQgPT09IHZvaWQgMCA/IHRydWUgOiBfcHJvcHMkaW5jbHVkZWQsXG4gICAgc3RhcnRQb2ludCA9IHByb3BzLnN0YXJ0UG9pbnQsXG4gICAgdHJhY2tTdHlsZSA9IHByb3BzLnRyYWNrU3R5bGUsXG4gICAgaGFuZGxlU3R5bGUgPSBwcm9wcy5oYW5kbGVTdHlsZSxcbiAgICByYWlsU3R5bGUgPSBwcm9wcy5yYWlsU3R5bGUsXG4gICAgZG90U3R5bGUgPSBwcm9wcy5kb3RTdHlsZSxcbiAgICBhY3RpdmVEb3RTdHlsZSA9IHByb3BzLmFjdGl2ZURvdFN0eWxlLFxuICAgIG1hcmtzID0gcHJvcHMubWFya3MsXG4gICAgZG90cyA9IHByb3BzLmRvdHMsXG4gICAgaGFuZGxlUmVuZGVyID0gcHJvcHMuaGFuZGxlUmVuZGVyLFxuICAgIF9wcm9wcyR0YWJJbmRleCA9IHByb3BzLnRhYkluZGV4LFxuICAgIHRhYkluZGV4ID0gX3Byb3BzJHRhYkluZGV4ID09PSB2b2lkIDAgPyAwIDogX3Byb3BzJHRhYkluZGV4LFxuICAgIGFyaWFMYWJlbEZvckhhbmRsZSA9IHByb3BzLmFyaWFMYWJlbEZvckhhbmRsZSxcbiAgICBhcmlhTGFiZWxsZWRCeUZvckhhbmRsZSA9IHByb3BzLmFyaWFMYWJlbGxlZEJ5Rm9ySGFuZGxlLFxuICAgIGFyaWFWYWx1ZVRleHRGb3JtYXR0ZXJGb3JIYW5kbGUgPSBwcm9wcy5hcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlO1xuICB2YXIgaGFuZGxlc1JlZiA9IFJlYWN0LnVzZVJlZigpO1xuICB2YXIgY29udGFpbmVyUmVmID0gUmVhY3QudXNlUmVmKCk7XG4gIHZhciBkaXJlY3Rpb24gPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodmVydGljYWwpIHtcbiAgICAgIHJldHVybiByZXZlcnNlID8gJ3R0YicgOiAnYnR0JztcbiAgICB9XG4gICAgcmV0dXJuIHJldmVyc2UgPyAncnRsJyA6ICdsdHInO1xuICB9LCBbcmV2ZXJzZSwgdmVydGljYWxdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSYW5nZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWVyZ2VkTWluID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGlzRmluaXRlKG1pbikgPyBtaW4gOiAwO1xuICB9LCBbbWluXSk7XG4gIHZhciBtZXJnZWRNYXggPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaXNGaW5pdGUobWF4KSA/IG1heCA6IDEwMDtcbiAgfSwgW21heF0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTdGVwID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBtZXJnZWRTdGVwID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHN0ZXAgIT09IG51bGwgJiYgc3RlcCA8PSAwID8gMSA6IHN0ZXA7XG4gIH0sIFtzdGVwXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFB1c2ggPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG1lcmdlZFB1c2ggPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAocHVzaGFibGUgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBtZXJnZWRTdGVwO1xuICAgIH1cbiAgICByZXR1cm4gcHVzaGFibGUgPj0gMCA/IHB1c2hhYmxlIDogZmFsc2U7XG4gIH0sIFtwdXNoYWJsZSwgbWVyZ2VkU3RlcF0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09IE1hcmtzID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBtYXJrTGlzdCA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobWFya3MgfHwge30pO1xuICAgIHJldHVybiBrZXlzLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICB2YXIgbWFyayA9IG1hcmtzW2tleV07XG4gICAgICB2YXIgbWFya09iaiA9IHtcbiAgICAgICAgdmFsdWU6IE51bWJlcihrZXkpXG4gICAgICB9O1xuICAgICAgaWYgKG1hcmsgJiYgX3R5cGVvZihtYXJrKSA9PT0gJ29iamVjdCcgJiYgISAvKiNfX1BVUkVfXyovUmVhY3QuaXNWYWxpZEVsZW1lbnQobWFyaykgJiYgKCdsYWJlbCcgaW4gbWFyayB8fCAnc3R5bGUnIGluIG1hcmspKSB7XG4gICAgICAgIG1hcmtPYmouc3R5bGUgPSBtYXJrLnN0eWxlO1xuICAgICAgICBtYXJrT2JqLmxhYmVsID0gbWFyay5sYWJlbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hcmtPYmoubGFiZWwgPSBtYXJrO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hcmtPYmo7XG4gICAgfSkuZmlsdGVyKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICB2YXIgbGFiZWwgPSBfcmVmLmxhYmVsO1xuICAgICAgcmV0dXJuIGxhYmVsIHx8IHR5cGVvZiBsYWJlbCA9PT0gJ251bWJlcic7XG4gICAgfSkuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEudmFsdWUgLSBiLnZhbHVlO1xuICAgIH0pO1xuICB9LCBbbWFya3NdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBGb3JtYXQgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgX3VzZU9mZnNldCA9IHVzZU9mZnNldChtZXJnZWRNaW4sIG1lcmdlZE1heCwgbWVyZ2VkU3RlcCwgbWFya0xpc3QsIGFsbG93Q3Jvc3MsIG1lcmdlZFB1c2gpLFxuICAgIF91c2VPZmZzZXQyID0gX3NsaWNlZFRvQXJyYXkoX3VzZU9mZnNldCwgMiksXG4gICAgZm9ybWF0VmFsdWUgPSBfdXNlT2Zmc2V0MlswXSxcbiAgICBvZmZzZXRWYWx1ZXMgPSBfdXNlT2Zmc2V0MlsxXTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBWYWx1ZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgX3VzZU1lcmdlZFN0YXRlID0gdXNlTWVyZ2VkU3RhdGUoZGVmYXVsdFZhbHVlLCB7XG4gICAgICB2YWx1ZTogdmFsdWVcbiAgICB9KSxcbiAgICBfdXNlTWVyZ2VkU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX3VzZU1lcmdlZFN0YXRlLCAyKSxcbiAgICBtZXJnZWRWYWx1ZSA9IF91c2VNZXJnZWRTdGF0ZTJbMF0sXG4gICAgc2V0VmFsdWUgPSBfdXNlTWVyZ2VkU3RhdGUyWzFdO1xuICB2YXIgcmF3VmFsdWVzID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHZhbHVlTGlzdCA9IG1lcmdlZFZhbHVlID09PSBudWxsIHx8IG1lcmdlZFZhbHVlID09PSB1bmRlZmluZWQgPyBbXSA6IEFycmF5LmlzQXJyYXkobWVyZ2VkVmFsdWUpID8gbWVyZ2VkVmFsdWUgOiBbbWVyZ2VkVmFsdWVdO1xuICAgIHZhciBfdmFsdWVMaXN0ID0gX3NsaWNlZFRvQXJyYXkodmFsdWVMaXN0LCAxKSxcbiAgICAgIF92YWx1ZUxpc3QkID0gX3ZhbHVlTGlzdFswXSxcbiAgICAgIHZhbDAgPSBfdmFsdWVMaXN0JCA9PT0gdm9pZCAwID8gbWVyZ2VkTWluIDogX3ZhbHVlTGlzdCQ7XG4gICAgdmFyIHJldHVyblZhbHVlcyA9IG1lcmdlZFZhbHVlID09PSBudWxsID8gW10gOiBbdmFsMF07XG4gICAgLy8gRm9ybWF0IGFzIHJhbmdlXG4gICAgaWYgKHJhbmdlKSB7XG4gICAgICByZXR1cm5WYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkodmFsdWVMaXN0KTtcbiAgICAgIC8vIFdoZW4gY291bnQgcHJvdmlkZWQgb3IgdmFsdWUgaXMgYHVuZGVmaW5lZGAsIHdlIGZpbGwgdmFsdWVzXG4gICAgICBpZiAoY291bnQgfHwgbWVyZ2VkVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgcG9pbnRDb3VudCA9IGNvdW50ID49IDAgPyBjb3VudCArIDEgOiAyO1xuICAgICAgICByZXR1cm5WYWx1ZXMgPSByZXR1cm5WYWx1ZXMuc2xpY2UoMCwgcG9pbnRDb3VudCk7XG4gICAgICAgIC8vIEZpbGwgd2l0aCBjb3VudFxuICAgICAgICB3aGlsZSAocmV0dXJuVmFsdWVzLmxlbmd0aCA8IHBvaW50Q291bnQpIHtcbiAgICAgICAgICB2YXIgX3JldHVyblZhbHVlcztcbiAgICAgICAgICByZXR1cm5WYWx1ZXMucHVzaCgoX3JldHVyblZhbHVlcyA9IHJldHVyblZhbHVlc1tyZXR1cm5WYWx1ZXMubGVuZ3RoIC0gMV0pICE9PSBudWxsICYmIF9yZXR1cm5WYWx1ZXMgIT09IHZvaWQgMCA/IF9yZXR1cm5WYWx1ZXMgOiBtZXJnZWRNaW4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm5WYWx1ZXMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICByZXR1cm4gYSAtIGI7XG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gQWxpZ24gaW4gcmFuZ2VcbiAgICByZXR1cm5WYWx1ZXMuZm9yRWFjaChmdW5jdGlvbiAodmFsLCBpbmRleCkge1xuICAgICAgcmV0dXJuVmFsdWVzW2luZGV4XSA9IGZvcm1hdFZhbHVlKHZhbCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldHVyblZhbHVlcztcbiAgfSwgW21lcmdlZFZhbHVlLCByYW5nZSwgbWVyZ2VkTWluLCBjb3VudCwgZm9ybWF0VmFsdWVdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IG9uQ2hhbmdlID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgcmF3VmFsdWVzUmVmID0gUmVhY3QudXNlUmVmKHJhd1ZhbHVlcyk7XG4gIHJhd1ZhbHVlc1JlZi5jdXJyZW50ID0gcmF3VmFsdWVzO1xuICB2YXIgZ2V0VHJpZ2dlclZhbHVlID0gZnVuY3Rpb24gZ2V0VHJpZ2dlclZhbHVlKHRyaWdnZXJWYWx1ZXMpIHtcbiAgICByZXR1cm4gcmFuZ2UgPyB0cmlnZ2VyVmFsdWVzIDogdHJpZ2dlclZhbHVlc1swXTtcbiAgfTtcbiAgdmFyIHRyaWdnZXJDaGFuZ2UgPSBmdW5jdGlvbiB0cmlnZ2VyQ2hhbmdlKG5leHRWYWx1ZXMpIHtcbiAgICAvLyBPcmRlciBmaXJzdFxuICAgIHZhciBjbG9uZU5leHRWYWx1ZXMgPSBfdG9Db25zdW1hYmxlQXJyYXkobmV4dFZhbHVlcykuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICAgIC8vIFRyaWdnZXIgZXZlbnQgaWYgbmVlZGVkXG4gICAgaWYgKG9uQ2hhbmdlICYmICFpc0VxdWFsKGNsb25lTmV4dFZhbHVlcywgcmF3VmFsdWVzUmVmLmN1cnJlbnQsIHRydWUpKSB7XG4gICAgICBvbkNoYW5nZShnZXRUcmlnZ2VyVmFsdWUoY2xvbmVOZXh0VmFsdWVzKSk7XG4gICAgfVxuICAgIC8vIFdlIHNldCB0aGlzIGxhdGVyIHNpbmNlIGl0IHdpbGwgcmUtcmVuZGVyIGNvbXBvbmVudCBpbW1lZGlhdGVseVxuICAgIHNldFZhbHVlKGNsb25lTmV4dFZhbHVlcyk7XG4gIH07XG4gIHZhciBjaGFuZ2VUb0Nsb3NlVmFsdWUgPSBmdW5jdGlvbiBjaGFuZ2VUb0Nsb3NlVmFsdWUobmV3VmFsdWUpIHtcbiAgICBpZiAoIWRpc2FibGVkKSB7XG4gICAgICB2YXIgdmFsdWVJbmRleCA9IDA7XG4gICAgICB2YXIgdmFsdWVEaXN0ID0gbWVyZ2VkTWF4IC0gbWVyZ2VkTWluO1xuICAgICAgcmF3VmFsdWVzLmZvckVhY2goZnVuY3Rpb24gKHZhbCwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGRpc3QgPSBNYXRoLmFicyhuZXdWYWx1ZSAtIHZhbCk7XG4gICAgICAgIGlmIChkaXN0IDw9IHZhbHVlRGlzdCkge1xuICAgICAgICAgIHZhbHVlRGlzdCA9IGRpc3Q7XG4gICAgICAgICAgdmFsdWVJbmRleCA9IGluZGV4O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIENyZWF0ZSBuZXcgdmFsdWVzXG4gICAgICB2YXIgY2xvbmVOZXh0VmFsdWVzID0gX3RvQ29uc3VtYWJsZUFycmF5KHJhd1ZhbHVlcyk7XG4gICAgICBjbG9uZU5leHRWYWx1ZXNbdmFsdWVJbmRleF0gPSBuZXdWYWx1ZTtcbiAgICAgIC8vIEZpbGwgdmFsdWUgdG8gbWF0Y2ggZGVmYXVsdCAyXG4gICAgICBpZiAocmFuZ2UgJiYgIXJhd1ZhbHVlcy5sZW5ndGggJiYgY291bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjbG9uZU5leHRWYWx1ZXMucHVzaChuZXdWYWx1ZSk7XG4gICAgICB9XG4gICAgICBvbkJlZm9yZUNoYW5nZSA9PT0gbnVsbCB8fCBvbkJlZm9yZUNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25CZWZvcmVDaGFuZ2UoZ2V0VHJpZ2dlclZhbHVlKGNsb25lTmV4dFZhbHVlcykpO1xuICAgICAgdHJpZ2dlckNoYW5nZShjbG9uZU5leHRWYWx1ZXMpO1xuICAgICAgb25BZnRlckNoYW5nZSA9PT0gbnVsbCB8fCBvbkFmdGVyQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkFmdGVyQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShjbG9uZU5leHRWYWx1ZXMpKTtcbiAgICB9XG4gIH07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ2xpY2sgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIG9uU2xpZGVyTW91c2VEb3duID0gZnVuY3Rpb24gb25TbGlkZXJNb3VzZURvd24oZSkge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB2YXIgX2NvbnRhaW5lclJlZiRjdXJyZW50ID0gY29udGFpbmVyUmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICB3aWR0aCA9IF9jb250YWluZXJSZWYkY3VycmVudC53aWR0aCxcbiAgICAgIGhlaWdodCA9IF9jb250YWluZXJSZWYkY3VycmVudC5oZWlnaHQsXG4gICAgICBsZWZ0ID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LmxlZnQsXG4gICAgICB0b3AgPSBfY29udGFpbmVyUmVmJGN1cnJlbnQudG9wLFxuICAgICAgYm90dG9tID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LmJvdHRvbSxcbiAgICAgIHJpZ2h0ID0gX2NvbnRhaW5lclJlZiRjdXJyZW50LnJpZ2h0O1xuICAgIHZhciBjbGllbnRYID0gZS5jbGllbnRYLFxuICAgICAgY2xpZW50WSA9IGUuY2xpZW50WTtcbiAgICB2YXIgcGVyY2VudDtcbiAgICBzd2l0Y2ggKGRpcmVjdGlvbikge1xuICAgICAgY2FzZSAnYnR0JzpcbiAgICAgICAgcGVyY2VudCA9IChib3R0b20gLSBjbGllbnRZKSAvIGhlaWdodDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd0dGInOlxuICAgICAgICBwZXJjZW50ID0gKGNsaWVudFkgLSB0b3ApIC8gaGVpZ2h0O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3J0bCc6XG4gICAgICAgIHBlcmNlbnQgPSAocmlnaHQgLSBjbGllbnRYKSAvIHdpZHRoO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBlcmNlbnQgPSAoY2xpZW50WCAtIGxlZnQpIC8gd2lkdGg7XG4gICAgfVxuICAgIHZhciBuZXh0VmFsdWUgPSBtZXJnZWRNaW4gKyBwZXJjZW50ICogKG1lcmdlZE1heCAtIG1lcmdlZE1pbik7XG4gICAgY2hhbmdlVG9DbG9zZVZhbHVlKGZvcm1hdFZhbHVlKG5leHRWYWx1ZSkpO1xuICB9O1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gS2V5Ym9hcmQgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZShudWxsKSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICBrZXlib2FyZFZhbHVlID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRLZXlib2FyZFZhbHVlID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgdmFyIG9uSGFuZGxlT2Zmc2V0Q2hhbmdlID0gZnVuY3Rpb24gb25IYW5kbGVPZmZzZXRDaGFuZ2Uob2Zmc2V0LCB2YWx1ZUluZGV4KSB7XG4gICAgaWYgKCFkaXNhYmxlZCkge1xuICAgICAgdmFyIG5leHQgPSBvZmZzZXRWYWx1ZXMocmF3VmFsdWVzLCBvZmZzZXQsIHZhbHVlSW5kZXgpO1xuICAgICAgb25CZWZvcmVDaGFuZ2UgPT09IG51bGwgfHwgb25CZWZvcmVDaGFuZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9uQmVmb3JlQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShyYXdWYWx1ZXMpKTtcbiAgICAgIHRyaWdnZXJDaGFuZ2UobmV4dC52YWx1ZXMpO1xuICAgICAgb25BZnRlckNoYW5nZSA9PT0gbnVsbCB8fCBvbkFmdGVyQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkFmdGVyQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShuZXh0LnZhbHVlcykpO1xuICAgICAgc2V0S2V5Ym9hcmRWYWx1ZShuZXh0LnZhbHVlKTtcbiAgICB9XG4gIH07XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGtleWJvYXJkVmFsdWUgIT09IG51bGwpIHtcbiAgICAgIHZhciB2YWx1ZUluZGV4ID0gcmF3VmFsdWVzLmluZGV4T2Yoa2V5Ym9hcmRWYWx1ZSk7XG4gICAgICBpZiAodmFsdWVJbmRleCA+PSAwKSB7XG4gICAgICAgIGhhbmRsZXNSZWYuY3VycmVudC5mb2N1cyh2YWx1ZUluZGV4KTtcbiAgICAgIH1cbiAgICB9XG4gICAgc2V0S2V5Ym9hcmRWYWx1ZShudWxsKTtcbiAgfSwgW2tleWJvYXJkVmFsdWVdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gRHJhZyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWVyZ2VkRHJhZ2dhYmxlVHJhY2sgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoZHJhZ2dhYmxlVHJhY2sgJiYgbWVyZ2VkU3RlcCA9PT0gbnVsbCkge1xuICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgd2FybmluZyhmYWxzZSwgJ2BkcmFnZ2FibGVUcmFja2AgaXMgbm90IHN1cHBvcnRlZCB3aGVuIGBzdGVwYCBpcyBgbnVsbGAuJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBkcmFnZ2FibGVUcmFjaztcbiAgfSwgW2RyYWdnYWJsZVRyYWNrLCBtZXJnZWRTdGVwXSk7XG4gIHZhciBmaW5pc2hDaGFuZ2UgPSBmdW5jdGlvbiBmaW5pc2hDaGFuZ2UoKSB7XG4gICAgb25BZnRlckNoYW5nZSA9PT0gbnVsbCB8fCBvbkFmdGVyQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkFmdGVyQ2hhbmdlKGdldFRyaWdnZXJWYWx1ZShyYXdWYWx1ZXNSZWYuY3VycmVudCkpO1xuICB9O1xuICB2YXIgX3VzZURyYWcgPSB1c2VEcmFnKGNvbnRhaW5lclJlZiwgZGlyZWN0aW9uLCByYXdWYWx1ZXMsIG1lcmdlZE1pbiwgbWVyZ2VkTWF4LCBmb3JtYXRWYWx1ZSwgdHJpZ2dlckNoYW5nZSwgZmluaXNoQ2hhbmdlLCBvZmZzZXRWYWx1ZXMpLFxuICAgIF91c2VEcmFnMiA9IF9zbGljZWRUb0FycmF5KF91c2VEcmFnLCA0KSxcbiAgICBkcmFnZ2luZ0luZGV4ID0gX3VzZURyYWcyWzBdLFxuICAgIGRyYWdnaW5nVmFsdWUgPSBfdXNlRHJhZzJbMV0sXG4gICAgY2FjaGVWYWx1ZXMgPSBfdXNlRHJhZzJbMl0sXG4gICAgb25TdGFydERyYWcgPSBfdXNlRHJhZzJbM107XG4gIHZhciBvblN0YXJ0TW92ZSA9IGZ1bmN0aW9uIG9uU3RhcnRNb3ZlKGUsIHZhbHVlSW5kZXgpIHtcbiAgICBvblN0YXJ0RHJhZyhlLCB2YWx1ZUluZGV4KTtcbiAgICBvbkJlZm9yZUNoYW5nZSA9PT0gbnVsbCB8fCBvbkJlZm9yZUNoYW5nZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25CZWZvcmVDaGFuZ2UoZ2V0VHJpZ2dlclZhbHVlKHJhd1ZhbHVlc1JlZi5jdXJyZW50KSk7XG4gIH07XG4gIC8vIEF1dG8gZm9jdXMgZm9yIHVwZGF0ZWQgaGFuZGxlXG4gIHZhciBkcmFnZ2luZyA9IGRyYWdnaW5nSW5kZXggIT09IC0xO1xuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmICghZHJhZ2dpbmcpIHtcbiAgICAgIHZhciB2YWx1ZUluZGV4ID0gcmF3VmFsdWVzLmxhc3RJbmRleE9mKGRyYWdnaW5nVmFsdWUpO1xuICAgICAgaGFuZGxlc1JlZi5jdXJyZW50LmZvY3VzKHZhbHVlSW5kZXgpO1xuICAgIH1cbiAgfSwgW2RyYWdnaW5nXSk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBJbmNsdWRlZCA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIHNvcnRlZENhY2hlVmFsdWVzID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIF90b0NvbnN1bWFibGVBcnJheShjYWNoZVZhbHVlcykuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgcmV0dXJuIGEgLSBiO1xuICAgIH0pO1xuICB9LCBbY2FjaGVWYWx1ZXNdKTtcbiAgLy8gUHJvdmlkZSBhIHJhbmdlIHZhbHVlcyB3aXRoIGluY2x1ZGVkIFttaW4sIG1heF1cbiAgLy8gVXNlZCBmb3IgVHJhY2ssIE1hcmsgJiBEb3RcbiAgdmFyIF9SZWFjdCR1c2VNZW1vID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAgIHJldHVybiBbbWVyZ2VkTWluLCBzb3J0ZWRDYWNoZVZhbHVlc1swXV07XG4gICAgICB9XG4gICAgICByZXR1cm4gW3NvcnRlZENhY2hlVmFsdWVzWzBdLCBzb3J0ZWRDYWNoZVZhbHVlc1tzb3J0ZWRDYWNoZVZhbHVlcy5sZW5ndGggLSAxXV07XG4gICAgfSwgW3NvcnRlZENhY2hlVmFsdWVzLCByYW5nZSwgbWVyZ2VkTWluXSksXG4gICAgX1JlYWN0JHVzZU1lbW8yID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZU1lbW8sIDIpLFxuICAgIGluY2x1ZGVkU3RhcnQgPSBfUmVhY3QkdXNlTWVtbzJbMF0sXG4gICAgaW5jbHVkZWRFbmQgPSBfUmVhY3QkdXNlTWVtbzJbMV07XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09IFJlZnMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgUmVhY3QudXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZm9jdXM6IGZ1bmN0aW9uIGZvY3VzKCkge1xuICAgICAgICBoYW5kbGVzUmVmLmN1cnJlbnQuZm9jdXMoMCk7XG4gICAgICB9LFxuICAgICAgYmx1cjogZnVuY3Rpb24gYmx1cigpIHtcbiAgICAgICAgdmFyIF9kb2N1bWVudCA9IGRvY3VtZW50LFxuICAgICAgICAgIGFjdGl2ZUVsZW1lbnQgPSBfZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgICAgaWYgKGNvbnRhaW5lclJlZi5jdXJyZW50LmNvbnRhaW5zKGFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgICAgYWN0aXZlRWxlbWVudCA9PT0gbnVsbCB8fCBhY3RpdmVFbGVtZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhY3RpdmVFbGVtZW50LmJsdXIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBBdXRvIEZvY3VzID09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGF1dG9Gb2N1cykge1xuICAgICAgaGFuZGxlc1JlZi5jdXJyZW50LmZvY3VzKDApO1xuICAgIH1cbiAgfSwgW10pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ29udGV4dCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBjb250ZXh0ID0gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1pbjogbWVyZ2VkTWluLFxuICAgICAgbWF4OiBtZXJnZWRNYXgsXG4gICAgICBkaXJlY3Rpb246IGRpcmVjdGlvbixcbiAgICAgIGRpc2FibGVkOiBkaXNhYmxlZCxcbiAgICAgIGtleWJvYXJkOiBrZXlib2FyZCxcbiAgICAgIHN0ZXA6IG1lcmdlZFN0ZXAsXG4gICAgICBpbmNsdWRlZDogaW5jbHVkZWQsXG4gICAgICBpbmNsdWRlZFN0YXJ0OiBpbmNsdWRlZFN0YXJ0LFxuICAgICAgaW5jbHVkZWRFbmQ6IGluY2x1ZGVkRW5kLFxuICAgICAgcmFuZ2U6IHJhbmdlLFxuICAgICAgdGFiSW5kZXg6IHRhYkluZGV4LFxuICAgICAgYXJpYUxhYmVsRm9ySGFuZGxlOiBhcmlhTGFiZWxGb3JIYW5kbGUsXG4gICAgICBhcmlhTGFiZWxsZWRCeUZvckhhbmRsZTogYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGUsXG4gICAgICBhcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlOiBhcmlhVmFsdWVUZXh0Rm9ybWF0dGVyRm9ySGFuZGxlXG4gICAgfTtcbiAgfSwgW21lcmdlZE1pbiwgbWVyZ2VkTWF4LCBkaXJlY3Rpb24sIGRpc2FibGVkLCBrZXlib2FyZCwgbWVyZ2VkU3RlcCwgaW5jbHVkZWQsIGluY2x1ZGVkU3RhcnQsIGluY2x1ZGVkRW5kLCByYW5nZSwgdGFiSW5kZXgsIGFyaWFMYWJlbEZvckhhbmRsZSwgYXJpYUxhYmVsbGVkQnlGb3JIYW5kbGUsIGFyaWFWYWx1ZVRleHRGb3JtYXR0ZXJGb3JIYW5kbGVdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoU2xpZGVyQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBjb250ZXh0XG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICByZWY6IGNvbnRhaW5lclJlZixcbiAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMocHJlZml4Q2xzLCBjbGFzc05hbWUsIChfY2xhc3NOYW1lcyA9IHt9LCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIFwiXCIuY29uY2F0KHByZWZpeENscywgXCItZGlzYWJsZWRcIiksIGRpc2FibGVkKSwgX2RlZmluZVByb3BlcnR5KF9jbGFzc05hbWVzLCBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLXZlcnRpY2FsXCIpLCB2ZXJ0aWNhbCksIF9kZWZpbmVQcm9wZXJ0eShfY2xhc3NOYW1lcywgXCJcIi5jb25jYXQocHJlZml4Q2xzLCBcIi1ob3Jpem9udGFsXCIpLCAhdmVydGljYWwpLCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIFwiXCIuY29uY2F0KHByZWZpeENscywgXCItd2l0aC1tYXJrc1wiKSwgbWFya0xpc3QubGVuZ3RoKSwgX2NsYXNzTmFtZXMpKSxcbiAgICBzdHlsZTogc3R5bGUsXG4gICAgb25Nb3VzZURvd246IG9uU2xpZGVyTW91c2VEb3duXG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItcmFpbFwiKSxcbiAgICBzdHlsZTogcmFpbFN0eWxlXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUcmFja3MsIHtcbiAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICBzdHlsZTogdHJhY2tTdHlsZSxcbiAgICB2YWx1ZXM6IHNvcnRlZENhY2hlVmFsdWVzLFxuICAgIHN0YXJ0UG9pbnQ6IHN0YXJ0UG9pbnQsXG4gICAgb25TdGFydE1vdmU6IG1lcmdlZERyYWdnYWJsZVRyYWNrID8gb25TdGFydE1vdmUgOiBudWxsXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChTdGVwcywge1xuICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgIG1hcmtzOiBtYXJrTGlzdCxcbiAgICBkb3RzOiBkb3RzLFxuICAgIHN0eWxlOiBkb3RTdHlsZSxcbiAgICBhY3RpdmVTdHlsZTogYWN0aXZlRG90U3R5bGVcbiAgfSksIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KEhhbmRsZXMsIHtcbiAgICByZWY6IGhhbmRsZXNSZWYsXG4gICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgc3R5bGU6IGhhbmRsZVN0eWxlLFxuICAgIHZhbHVlczogY2FjaGVWYWx1ZXMsXG4gICAgZHJhZ2dpbmdJbmRleDogZHJhZ2dpbmdJbmRleCxcbiAgICBvblN0YXJ0TW92ZTogb25TdGFydE1vdmUsXG4gICAgb25PZmZzZXRDaGFuZ2U6IG9uSGFuZGxlT2Zmc2V0Q2hhbmdlLFxuICAgIG9uRm9jdXM6IG9uRm9jdXMsXG4gICAgb25CbHVyOiBvbkJsdXIsXG4gICAgaGFuZGxlUmVuZGVyOiBoYW5kbGVSZW5kZXJcbiAgfSksIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1hcmtzLCB7XG4gICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgbWFya3M6IG1hcmtMaXN0LFxuICAgIG9uQ2xpY2s6IGNoYW5nZVRvQ2xvc2VWYWx1ZVxuICB9KSkpO1xufSk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBTbGlkZXIuZGlzcGxheU5hbWUgPSAnU2xpZGVyJztcbn1cbmV4cG9ydCBkZWZhdWx0IFNsaWRlcjsiLCJpbXBvcnQgU2xpZGVyIGZyb20gJy4vU2xpZGVyJztcbmV4cG9ydCBkZWZhdWx0IFNsaWRlcjsiLCJcbiAgICAgIGltcG9ydCBBUEkgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luamVjdFN0eWxlc0ludG9TdHlsZVRhZy5qc1wiO1xuICAgICAgaW1wb3J0IGRvbUFQSSBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0QnlTZWxlY3Rvci5qc1wiO1xuICAgICAgaW1wb3J0IHNldEF0dHJpYnV0ZXMgZnJvbSBcIiEuLi8uLi9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydFN0eWxlRWxlbWVudCBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanNcIjtcbiAgICAgIGltcG9ydCBjb250ZW50LCAqIGFzIG5hbWVkRXhwb3J0IGZyb20gXCIhIS4uLy4uL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9ib290c3RyYXAuY3NzXCI7XG4gICAgICBcbiAgICAgIFxuXG52YXIgb3B0aW9ucyA9IHt9O1xuXG5vcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtID0gc3R5bGVUYWdUcmFuc2Zvcm1Gbjtcbm9wdGlvbnMuc2V0QXR0cmlidXRlcyA9IHNldEF0dHJpYnV0ZXM7XG5cbiAgICAgIG9wdGlvbnMuaW5zZXJ0ID0gaW5zZXJ0Rm4uYmluZChudWxsLCBcImhlYWRcIik7XG4gICAgXG5vcHRpb25zLmRvbUFQSSA9IGRvbUFQSTtcbm9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50ID0gaW5zZXJ0U3R5bGVFbGVtZW50O1xuXG52YXIgdXBkYXRlID0gQVBJKGNvbnRlbnQsIG9wdGlvbnMpO1xuXG5cblxuZXhwb3J0ICogZnJvbSBcIiEhLi4vLi4vY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2Jvb3RzdHJhcC5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VNZW1vKGdldFZhbHVlLCBjb25kaXRpb24sIHNob3VsZFVwZGF0ZSkge1xuICB2YXIgY2FjaGVSZWYgPSBSZWFjdC51c2VSZWYoe30pO1xuICBpZiAoISgndmFsdWUnIGluIGNhY2hlUmVmLmN1cnJlbnQpIHx8IHNob3VsZFVwZGF0ZShjYWNoZVJlZi5jdXJyZW50LmNvbmRpdGlvbiwgY29uZGl0aW9uKSkge1xuICAgIGNhY2hlUmVmLmN1cnJlbnQudmFsdWUgPSBnZXRWYWx1ZSgpO1xuICAgIGNhY2hlUmVmLmN1cnJlbnQuY29uZGl0aW9uID0gY29uZGl0aW9uO1xuICB9XG4gIHJldHVybiBjYWNoZVJlZi5jdXJyZW50LnZhbHVlO1xufSIsImltcG9ydCBfdHlwZW9mIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90eXBlb2ZcIjtcbi8qIGVzbGludC1kaXNhYmxlIG5vLXBhcmFtLXJlYXNzaWduICovXG5cbmltcG9ydCB7IGlzTWVtbyB9IGZyb20gJ3JlYWN0LWlzJztcbmltcG9ydCB1c2VNZW1vIGZyb20gXCIuL2hvb2tzL3VzZU1lbW9cIjtcbmV4cG9ydCBmdW5jdGlvbiBmaWxsUmVmKHJlZiwgbm9kZSkge1xuICBpZiAodHlwZW9mIHJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJlZihub2RlKTtcbiAgfSBlbHNlIGlmIChfdHlwZW9mKHJlZikgPT09ICdvYmplY3QnICYmIHJlZiAmJiAnY3VycmVudCcgaW4gcmVmKSB7XG4gICAgcmVmLmN1cnJlbnQgPSBub2RlO1xuICB9XG59XG5cbi8qKlxuICogTWVyZ2UgcmVmcyBpbnRvIG9uZSByZWYgZnVuY3Rpb24gdG8gc3VwcG9ydCByZWYgcGFzc2luZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VSZWYoKSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCByZWZzID0gbmV3IEFycmF5KF9sZW4pLCBfa2V5ID0gMDsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIHJlZnNbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cbiAgdmFyIHJlZkxpc3QgPSByZWZzLmZpbHRlcihmdW5jdGlvbiAocmVmKSB7XG4gICAgcmV0dXJuIHJlZjtcbiAgfSk7XG4gIGlmIChyZWZMaXN0Lmxlbmd0aCA8PSAxKSB7XG4gICAgcmV0dXJuIHJlZkxpc3RbMF07XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmVmcy5mb3JFYWNoKGZ1bmN0aW9uIChyZWYpIHtcbiAgICAgIGZpbGxSZWYocmVmLCBub2RlKTtcbiAgICB9KTtcbiAgfTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1c2VDb21wb3NlUmVmKCkge1xuICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIHJlZnMgPSBuZXcgQXJyYXkoX2xlbjIpLCBfa2V5MiA9IDA7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICByZWZzW19rZXkyXSA9IGFyZ3VtZW50c1tfa2V5Ml07XG4gIH1cbiAgcmV0dXJuIHVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjb21wb3NlUmVmLmFwcGx5KHZvaWQgMCwgcmVmcyk7XG4gIH0sIHJlZnMsIGZ1bmN0aW9uIChwcmV2LCBuZXh0KSB7XG4gICAgcmV0dXJuIHByZXYubGVuZ3RoID09PSBuZXh0Lmxlbmd0aCAmJiBwcmV2LmV2ZXJ5KGZ1bmN0aW9uIChyZWYsIGkpIHtcbiAgICAgIHJldHVybiByZWYgPT09IG5leHRbaV07XG4gICAgfSk7XG4gIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHN1cHBvcnRSZWYobm9kZU9yQ29tcG9uZW50KSB7XG4gIHZhciBfdHlwZSRwcm90b3R5cGUsIF9ub2RlT3JDb21wb25lbnQkcHJvdDtcbiAgdmFyIHR5cGUgPSBpc01lbW8obm9kZU9yQ29tcG9uZW50KSA/IG5vZGVPckNvbXBvbmVudC50eXBlLnR5cGUgOiBub2RlT3JDb21wb25lbnQudHlwZTtcblxuICAvLyBGdW5jdGlvbiBjb21wb25lbnQgbm9kZVxuICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicgJiYgISgoX3R5cGUkcHJvdG90eXBlID0gdHlwZS5wcm90b3R5cGUpICE9PSBudWxsICYmIF90eXBlJHByb3RvdHlwZSAhPT0gdm9pZCAwICYmIF90eXBlJHByb3RvdHlwZS5yZW5kZXIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gQ2xhc3MgY29tcG9uZW50XG4gIGlmICh0eXBlb2Ygbm9kZU9yQ29tcG9uZW50ID09PSAnZnVuY3Rpb24nICYmICEoKF9ub2RlT3JDb21wb25lbnQkcHJvdCA9IG5vZGVPckNvbXBvbmVudC5wcm90b3R5cGUpICE9PSBudWxsICYmIF9ub2RlT3JDb21wb25lbnQkcHJvdCAhPT0gdm9pZCAwICYmIF9ub2RlT3JDb21wb25lbnQkcHJvdC5yZW5kZXIpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuLyogZXNsaW50LWVuYWJsZSAqLyIsImltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbnZhciBPcmRlckNvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dChudWxsKTtcbmV4cG9ydCBkZWZhdWx0IE9yZGVyQ29udGV4dDsiLCJpbXBvcnQgX3RvQ29uc3VtYWJsZUFycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS90b0NvbnN1bWFibGVBcnJheVwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgdXNlTGF5b3V0RWZmZWN0IGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUxheW91dEVmZmVjdFwiO1xuaW1wb3J0IGNhblVzZURvbSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vY2FuVXNlRG9tXCI7XG5pbXBvcnQgT3JkZXJDb250ZXh0IGZyb20gXCIuL0NvbnRleHRcIjtcbnZhciBFTVBUWV9MSVNUID0gW107XG5cbi8qKlxuICogV2lsbCBhZGQgYGRpdmAgdG8gZG9jdW1lbnQuIE5lc3QgY2FsbCB3aWxsIGtlZXAgb3JkZXJcbiAqIEBwYXJhbSByZW5kZXIgUmVuZGVyIERPTSBpbiBkb2N1bWVudFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VEb20ocmVuZGVyLCBkZWJ1Zykge1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKCFjYW5Vc2VEb20oKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHZhciBkZWZhdWx0RWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyAmJiBkZWJ1Zykge1xuICAgICAgICBkZWZhdWx0RWxlLnNldEF0dHJpYnV0ZSgnZGF0YS1kZWJ1ZycsIGRlYnVnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWZhdWx0RWxlO1xuICAgIH0pLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDEpLFxuICAgIGVsZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMF07XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gT3JkZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGFwcGVuZGVkUmVmID0gUmVhY3QudXNlUmVmKGZhbHNlKTtcbiAgdmFyIHF1ZXVlQ3JlYXRlID0gUmVhY3QudXNlQ29udGV4dChPcmRlckNvbnRleHQpO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlMyA9IFJlYWN0LnVzZVN0YXRlKEVNUFRZX0xJU1QpLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTQgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUzLCAyKSxcbiAgICBxdWV1ZSA9IF9SZWFjdCR1c2VTdGF0ZTRbMF0sXG4gICAgc2V0UXVldWUgPSBfUmVhY3QkdXNlU3RhdGU0WzFdO1xuICB2YXIgbWVyZ2VkUXVldWVDcmVhdGUgPSBxdWV1ZUNyZWF0ZSB8fCAoYXBwZW5kZWRSZWYuY3VycmVudCA/IHVuZGVmaW5lZCA6IGZ1bmN0aW9uIChhcHBlbmRGbikge1xuICAgIHNldFF1ZXVlKGZ1bmN0aW9uIChvcmlnaW4pIHtcbiAgICAgIHZhciBuZXdRdWV1ZSA9IFthcHBlbmRGbl0uY29uY2F0KF90b0NvbnN1bWFibGVBcnJheShvcmlnaW4pKTtcbiAgICAgIHJldHVybiBuZXdRdWV1ZTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IERPTSA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgZnVuY3Rpb24gYXBwZW5kKCkge1xuICAgIGlmICghZWxlLnBhcmVudEVsZW1lbnQpIHtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZWxlKTtcbiAgICB9XG4gICAgYXBwZW5kZWRSZWYuY3VycmVudCA9IHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICB2YXIgX2VsZSRwYXJlbnRFbGVtZW50O1xuICAgIChfZWxlJHBhcmVudEVsZW1lbnQgPSBlbGUucGFyZW50RWxlbWVudCkgPT09IG51bGwgfHwgX2VsZSRwYXJlbnRFbGVtZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZWxlJHBhcmVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoZWxlKTtcbiAgICBhcHBlbmRlZFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gIH1cbiAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAocmVuZGVyKSB7XG4gICAgICBpZiAocXVldWVDcmVhdGUpIHtcbiAgICAgICAgcXVldWVDcmVhdGUoYXBwZW5kKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFwcGVuZCgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGVhbnVwKCk7XG4gICAgfVxuICAgIHJldHVybiBjbGVhbnVwO1xuICB9LCBbcmVuZGVyXSk7XG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgcXVldWUuZm9yRWFjaChmdW5jdGlvbiAoYXBwZW5kRm4pIHtcbiAgICAgICAgcmV0dXJuIGFwcGVuZEZuKCk7XG4gICAgICB9KTtcbiAgICAgIHNldFF1ZXVlKEVNUFRZX0xJU1QpO1xuICAgIH1cbiAgfSwgW3F1ZXVlXSk7XG4gIHJldHVybiBbZWxlLCBtZXJnZWRRdWV1ZUNyZWF0ZV07XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY29udGFpbnMocm9vdCwgbikge1xuICBpZiAoIXJvb3QpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBVc2UgbmF0aXZlIGlmIHN1cHBvcnRcbiAgaWYgKHJvb3QuY29udGFpbnMpIHtcbiAgICByZXR1cm4gcm9vdC5jb250YWlucyhuKTtcbiAgfVxuXG4gIC8vIGBkb2N1bWVudC5jb250YWluc2Agbm90IHN1cHBvcnQgd2l0aCBJRTExXG4gIHZhciBub2RlID0gbjtcbiAgd2hpbGUgKG5vZGUpIHtcbiAgICBpZiAobm9kZSA9PT0gcm9vdCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufSIsImltcG9ydCBjYW5Vc2VEb20gZnJvbSBcIi4vY2FuVXNlRG9tXCI7XG5pbXBvcnQgY29udGFpbnMgZnJvbSBcIi4vY29udGFpbnNcIjtcbnZhciBBUFBFTkRfT1JERVIgPSAnZGF0YS1yYy1vcmRlcic7XG52YXIgTUFSS19LRVkgPSBcInJjLXV0aWwta2V5XCI7XG52YXIgY29udGFpbmVyQ2FjaGUgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBnZXRNYXJrKCkge1xuICB2YXIgX3JlZiA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDoge30sXG4gICAgbWFyayA9IF9yZWYubWFyaztcbiAgaWYgKG1hcmspIHtcbiAgICByZXR1cm4gbWFyay5zdGFydHNXaXRoKCdkYXRhLScpID8gbWFyayA6IFwiZGF0YS1cIi5jb25jYXQobWFyayk7XG4gIH1cbiAgcmV0dXJuIE1BUktfS0VZO1xufVxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyKG9wdGlvbikge1xuICBpZiAob3B0aW9uLmF0dGFjaFRvKSB7XG4gICAgcmV0dXJuIG9wdGlvbi5hdHRhY2hUbztcbiAgfVxuICB2YXIgaGVhZCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2hlYWQnKTtcbiAgcmV0dXJuIGhlYWQgfHwgZG9jdW1lbnQuYm9keTtcbn1cbmZ1bmN0aW9uIGdldE9yZGVyKHByZXBlbmQpIHtcbiAgaWYgKHByZXBlbmQgPT09ICdxdWV1ZScpIHtcbiAgICByZXR1cm4gJ3ByZXBlbmRRdWV1ZSc7XG4gIH1cbiAgcmV0dXJuIHByZXBlbmQgPyAncHJlcGVuZCcgOiAnYXBwZW5kJztcbn1cblxuLyoqXG4gKiBGaW5kIHN0eWxlIHdoaWNoIGluamVjdCBieSByYy11dGlsXG4gKi9cbmZ1bmN0aW9uIGZpbmRTdHlsZXMoY29udGFpbmVyKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKChjb250YWluZXJDYWNoZS5nZXQoY29udGFpbmVyKSB8fCBjb250YWluZXIpLmNoaWxkcmVuKS5maWx0ZXIoZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS50YWdOYW1lID09PSAnU1RZTEUnO1xuICB9KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RDU1MoY3NzKSB7XG4gIHZhciBvcHRpb24gPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICBpZiAoIWNhblVzZURvbSgpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgdmFyIGNzcCA9IG9wdGlvbi5jc3AsXG4gICAgcHJlcGVuZCA9IG9wdGlvbi5wcmVwZW5kO1xuICB2YXIgc3R5bGVOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgc3R5bGVOb2RlLnNldEF0dHJpYnV0ZShBUFBFTkRfT1JERVIsIGdldE9yZGVyKHByZXBlbmQpKTtcbiAgaWYgKGNzcCAhPT0gbnVsbCAmJiBjc3AgIT09IHZvaWQgMCAmJiBjc3Aubm9uY2UpIHtcbiAgICBzdHlsZU5vZGUubm9uY2UgPSBjc3AgPT09IG51bGwgfHwgY3NwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBjc3Aubm9uY2U7XG4gIH1cbiAgc3R5bGVOb2RlLmlubmVySFRNTCA9IGNzcztcbiAgdmFyIGNvbnRhaW5lciA9IGdldENvbnRhaW5lcihvcHRpb24pO1xuICB2YXIgZmlyc3RDaGlsZCA9IGNvbnRhaW5lci5maXJzdENoaWxkO1xuICBpZiAocHJlcGVuZCkge1xuICAgIC8vIElmIGlzIHF1ZXVlIGBwcmVwZW5kYCwgaXQgd2lsbCBwcmVwZW5kIGZpcnN0IHN0eWxlIGFuZCB0aGVuIGFwcGVuZCByZXN0IHN0eWxlXG4gICAgaWYgKHByZXBlbmQgPT09ICdxdWV1ZScpIHtcbiAgICAgIHZhciBleGlzdFN0eWxlID0gZmluZFN0eWxlcyhjb250YWluZXIpLmZpbHRlcihmdW5jdGlvbiAobm9kZSkge1xuICAgICAgICByZXR1cm4gWydwcmVwZW5kJywgJ3ByZXBlbmRRdWV1ZSddLmluY2x1ZGVzKG5vZGUuZ2V0QXR0cmlidXRlKEFQUEVORF9PUkRFUikpO1xuICAgICAgfSk7XG4gICAgICBpZiAoZXhpc3RTdHlsZS5sZW5ndGgpIHtcbiAgICAgICAgY29udGFpbmVyLmluc2VydEJlZm9yZShzdHlsZU5vZGUsIGV4aXN0U3R5bGVbZXhpc3RTdHlsZS5sZW5ndGggLSAxXS5uZXh0U2libGluZyk7XG4gICAgICAgIHJldHVybiBzdHlsZU5vZGU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVXNlIGBpbnNlcnRCZWZvcmVgIGFzIGBwcmVwZW5kYFxuICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUoc3R5bGVOb2RlLCBmaXJzdENoaWxkKTtcbiAgfSBlbHNlIHtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoc3R5bGVOb2RlKTtcbiAgfVxuICByZXR1cm4gc3R5bGVOb2RlO1xufVxuZnVuY3Rpb24gZmluZEV4aXN0Tm9kZShrZXkpIHtcbiAgdmFyIG9wdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG4gIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIob3B0aW9uKTtcbiAgcmV0dXJuIGZpbmRTdHlsZXMoY29udGFpbmVyKS5maW5kKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlKGdldE1hcmsob3B0aW9uKSkgPT09IGtleTtcbiAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlQ1NTKGtleSkge1xuICB2YXIgb3B0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcbiAgdmFyIGV4aXN0Tm9kZSA9IGZpbmRFeGlzdE5vZGUoa2V5LCBvcHRpb24pO1xuICBpZiAoZXhpc3ROb2RlKSB7XG4gICAgdmFyIGNvbnRhaW5lciA9IGdldENvbnRhaW5lcihvcHRpb24pO1xuICAgIGNvbnRhaW5lci5yZW1vdmVDaGlsZChleGlzdE5vZGUpO1xuICB9XG59XG5cbi8qKlxuICogcWlhbmt1biB3aWxsIGluamVjdCBgYXBwZW5kQ2hpbGRgIHRvIGluc2VydCBpbnRvIG90aGVyXG4gKi9cbmZ1bmN0aW9uIHN5bmNSZWFsQ29udGFpbmVyKGNvbnRhaW5lciwgb3B0aW9uKSB7XG4gIHZhciBjYWNoZWRSZWFsQ29udGFpbmVyID0gY29udGFpbmVyQ2FjaGUuZ2V0KGNvbnRhaW5lcik7XG5cbiAgLy8gRmluZCByZWFsIGNvbnRhaW5lciB3aGVuIG5vdCBjYWNoZWQgb3IgY2FjaGVkIGNvbnRhaW5lciByZW1vdmVkXG4gIGlmICghY2FjaGVkUmVhbENvbnRhaW5lciB8fCAhY29udGFpbnMoZG9jdW1lbnQsIGNhY2hlZFJlYWxDb250YWluZXIpKSB7XG4gICAgdmFyIHBsYWNlaG9sZGVyU3R5bGUgPSBpbmplY3RDU1MoJycsIG9wdGlvbik7XG4gICAgdmFyIHBhcmVudE5vZGUgPSBwbGFjZWhvbGRlclN0eWxlLnBhcmVudE5vZGU7XG4gICAgY29udGFpbmVyQ2FjaGUuc2V0KGNvbnRhaW5lciwgcGFyZW50Tm9kZSk7XG4gICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHBsYWNlaG9sZGVyU3R5bGUpO1xuICB9XG59XG5cbi8qKlxuICogbWFudWFsbHkgY2xlYXIgY29udGFpbmVyIGNhY2hlIHRvIGF2b2lkIGdsb2JhbCBjYWNoZSBpbiB1bml0IHRlc3Rlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJDb250YWluZXJDYWNoZSgpIHtcbiAgY29udGFpbmVyQ2FjaGUuY2xlYXIoKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDU1MoY3NzLCBrZXkpIHtcbiAgdmFyIG9wdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge307XG4gIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIob3B0aW9uKTtcblxuICAvLyBTeW5jIHJlYWwgcGFyZW50XG4gIHN5bmNSZWFsQ29udGFpbmVyKGNvbnRhaW5lciwgb3B0aW9uKTtcbiAgdmFyIGV4aXN0Tm9kZSA9IGZpbmRFeGlzdE5vZGUoa2V5LCBvcHRpb24pO1xuICBpZiAoZXhpc3ROb2RlKSB7XG4gICAgdmFyIF9vcHRpb24kY3NwLCBfb3B0aW9uJGNzcDI7XG4gICAgaWYgKChfb3B0aW9uJGNzcCA9IG9wdGlvbi5jc3ApICE9PSBudWxsICYmIF9vcHRpb24kY3NwICE9PSB2b2lkIDAgJiYgX29wdGlvbiRjc3Aubm9uY2UgJiYgZXhpc3ROb2RlLm5vbmNlICE9PSAoKF9vcHRpb24kY3NwMiA9IG9wdGlvbi5jc3ApID09PSBudWxsIHx8IF9vcHRpb24kY3NwMiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX29wdGlvbiRjc3AyLm5vbmNlKSkge1xuICAgICAgdmFyIF9vcHRpb24kY3NwMztcbiAgICAgIGV4aXN0Tm9kZS5ub25jZSA9IChfb3B0aW9uJGNzcDMgPSBvcHRpb24uY3NwKSA9PT0gbnVsbCB8fCBfb3B0aW9uJGNzcDMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9vcHRpb24kY3NwMy5ub25jZTtcbiAgICB9XG4gICAgaWYgKGV4aXN0Tm9kZS5pbm5lckhUTUwgIT09IGNzcykge1xuICAgICAgZXhpc3ROb2RlLmlubmVySFRNTCA9IGNzcztcbiAgICB9XG4gICAgcmV0dXJuIGV4aXN0Tm9kZTtcbiAgfVxuICB2YXIgbmV3Tm9kZSA9IGluamVjdENTUyhjc3MsIG9wdGlvbik7XG4gIG5ld05vZGUuc2V0QXR0cmlidXRlKGdldE1hcmsob3B0aW9uKSwga2V5KTtcbiAgcmV0dXJuIG5ld05vZGU7XG59IiwiLyogZXNsaW50LWRpc2FibGUgbm8tcGFyYW0tcmVhc3NpZ24gKi9cblxudmFyIGNhY2hlZDtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFNjcm9sbEJhclNpemUoZnJlc2gpIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuICBpZiAoZnJlc2ggfHwgY2FjaGVkID09PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgaW5uZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBpbm5lci5zdHlsZS53aWR0aCA9ICcxMDAlJztcbiAgICBpbm5lci5zdHlsZS5oZWlnaHQgPSAnMjAwcHgnO1xuICAgIHZhciBvdXRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHZhciBvdXRlclN0eWxlID0gb3V0ZXIuc3R5bGU7XG4gICAgb3V0ZXJTdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgb3V0ZXJTdHlsZS50b3AgPSAnMCc7XG4gICAgb3V0ZXJTdHlsZS5sZWZ0ID0gJzAnO1xuICAgIG91dGVyU3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcbiAgICBvdXRlclN0eWxlLnZpc2liaWxpdHkgPSAnaGlkZGVuJztcbiAgICBvdXRlclN0eWxlLndpZHRoID0gJzIwMHB4JztcbiAgICBvdXRlclN0eWxlLmhlaWdodCA9ICcxNTBweCc7XG4gICAgb3V0ZXJTdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgIG91dGVyLmFwcGVuZENoaWxkKGlubmVyKTtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKG91dGVyKTtcbiAgICB2YXIgd2lkdGhDb250YWluZWQgPSBpbm5lci5vZmZzZXRXaWR0aDtcbiAgICBvdXRlci5zdHlsZS5vdmVyZmxvdyA9ICdzY3JvbGwnO1xuICAgIHZhciB3aWR0aFNjcm9sbCA9IGlubmVyLm9mZnNldFdpZHRoO1xuICAgIGlmICh3aWR0aENvbnRhaW5lZCA9PT0gd2lkdGhTY3JvbGwpIHtcbiAgICAgIHdpZHRoU2Nyb2xsID0gb3V0ZXIuY2xpZW50V2lkdGg7XG4gICAgfVxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQob3V0ZXIpO1xuICAgIGNhY2hlZCA9IHdpZHRoQ29udGFpbmVkIC0gd2lkdGhTY3JvbGw7XG4gIH1cbiAgcmV0dXJuIGNhY2hlZDtcbn1cbmZ1bmN0aW9uIGVuc3VyZVNpemUoc3RyKSB7XG4gIHZhciBtYXRjaCA9IHN0ci5tYXRjaCgvXiguKilweCQvKTtcbiAgdmFyIHZhbHVlID0gTnVtYmVyKG1hdGNoID09PSBudWxsIHx8IG1hdGNoID09PSB2b2lkIDAgPyB2b2lkIDAgOiBtYXRjaFsxXSk7XG4gIHJldHVybiBOdW1iZXIuaXNOYU4odmFsdWUpID8gZ2V0U2Nyb2xsQmFyU2l6ZSgpIDogdmFsdWU7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0VGFyZ2V0U2Nyb2xsQmFyU2l6ZSh0YXJnZXQpIHtcbiAgaWYgKHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgIXRhcmdldCB8fCAhKHRhcmdldCBpbnN0YW5jZW9mIEVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwXG4gICAgfTtcbiAgfVxuICB2YXIgX2dldENvbXB1dGVkU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKHRhcmdldCwgJzo6LXdlYmtpdC1zY3JvbGxiYXInKSxcbiAgICB3aWR0aCA9IF9nZXRDb21wdXRlZFN0eWxlLndpZHRoLFxuICAgIGhlaWdodCA9IF9nZXRDb21wdXRlZFN0eWxlLmhlaWdodDtcbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogZW5zdXJlU2l6ZSh3aWR0aCksXG4gICAgaGVpZ2h0OiBlbnN1cmVTaXplKGhlaWdodClcbiAgfTtcbn0iLCIvKipcbiAqIFRlc3QgdXNhZ2UgZXhwb3J0LiBEbyBub3QgdXNlIGluIHlvdXIgcHJvZHVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCb2R5T3ZlcmZsb3dpbmcoKSB7XG4gIHJldHVybiBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCA+ICh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCkgJiYgd2luZG93LmlubmVyV2lkdGggPiBkb2N1bWVudC5ib2R5Lm9mZnNldFdpZHRoO1xufSIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXBkYXRlQ1NTLCByZW1vdmVDU1MgfSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vZHluYW1pY0NTU1wiO1xuaW1wb3J0IHVzZUxheW91dEVmZmVjdCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCBnZXRTY3JvbGxCYXJTaXplIGZyb20gXCJyYy11dGlsL2VzL2dldFNjcm9sbEJhclNpemVcIjtcbmltcG9ydCB7IGlzQm9keU92ZXJmbG93aW5nIH0gZnJvbSBcIi4vdXRpbFwiO1xudmFyIFVOSVFVRV9JRCA9IFwicmMtdXRpbC1sb2NrZXItXCIuY29uY2F0KERhdGUubm93KCkpO1xudmFyIHV1aWQgPSAwO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlU2Nyb2xsTG9ja2VyKGxvY2spIHtcbiAgdmFyIG1lcmdlZExvY2sgPSAhIWxvY2s7XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICB1dWlkICs9IDE7XG4gICAgICByZXR1cm4gXCJcIi5jb25jYXQoVU5JUVVFX0lELCBcIl9cIikuY29uY2F0KHV1aWQpO1xuICAgIH0pLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDEpLFxuICAgIGlkID0gX1JlYWN0JHVzZVN0YXRlMlswXTtcbiAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAobWVyZ2VkTG9jaykge1xuICAgICAgdmFyIHNjcm9sbGJhclNpemUgPSBnZXRTY3JvbGxCYXJTaXplKCk7XG4gICAgICB2YXIgaXNPdmVyZmxvdyA9IGlzQm9keU92ZXJmbG93aW5nKCk7XG4gICAgICB1cGRhdGVDU1MoXCJcXG5odG1sIGJvZHkge1xcbiAgb3ZlcmZsb3cteTogaGlkZGVuO1xcbiAgXCIuY29uY2F0KGlzT3ZlcmZsb3cgPyBcIndpZHRoOiBjYWxjKDEwMCUgLSBcIi5jb25jYXQoc2Nyb2xsYmFyU2l6ZSwgXCJweCk7XCIpIDogJycsIFwiXFxufVwiKSwgaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZW1vdmVDU1MoaWQpO1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmVtb3ZlQ1NTKGlkKTtcbiAgICB9O1xuICB9LCBbbWVyZ2VkTG9jaywgaWRdKTtcbn0iLCJleHBvcnQgdmFyIGlubGluZSA9IGZhbHNlO1xuZXhwb3J0IGZ1bmN0aW9uIGlubGluZU1vY2sobmV4dElubGluZSkge1xuICBpZiAodHlwZW9mIG5leHRJbmxpbmUgPT09ICdib29sZWFuJykge1xuICAgIGlubGluZSA9IG5leHRJbmxpbmU7XG4gIH1cbiAgcmV0dXJuIGlubGluZTtcbn0iLCJpbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNyZWF0ZVBvcnRhbCB9IGZyb20gJ3JlYWN0LWRvbSc7XG5pbXBvcnQgY2FuVXNlRG9tIGZyb20gXCJyYy11dGlsL2VzL0RvbS9jYW5Vc2VEb21cIjtcbmltcG9ydCB3YXJuaW5nIGZyb20gXCJyYy11dGlsL2VzL3dhcm5pbmdcIjtcbmltcG9ydCB7IHN1cHBvcnRSZWYsIHVzZUNvbXBvc2VSZWYgfSBmcm9tIFwicmMtdXRpbC9lcy9yZWZcIjtcbmltcG9ydCBPcmRlckNvbnRleHQgZnJvbSBcIi4vQ29udGV4dFwiO1xuaW1wb3J0IHVzZURvbSBmcm9tIFwiLi91c2VEb21cIjtcbmltcG9ydCB1c2VTY3JvbGxMb2NrZXIgZnJvbSBcIi4vdXNlU2Nyb2xsTG9ja2VyXCI7XG5pbXBvcnQgeyBpbmxpbmVNb2NrIH0gZnJvbSBcIi4vbW9ja1wiO1xudmFyIGdldFBvcnRhbENvbnRhaW5lciA9IGZ1bmN0aW9uIGdldFBvcnRhbENvbnRhaW5lcihnZXRDb250YWluZXIpIHtcbiAgaWYgKGdldENvbnRhaW5lciA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCFjYW5Vc2VEb20oKSB8fCAhZ2V0Q29udGFpbmVyKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKHR5cGVvZiBnZXRDb250YWluZXIgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZ2V0Q29udGFpbmVyKTtcbiAgfVxuICBpZiAodHlwZW9mIGdldENvbnRhaW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBnZXRDb250YWluZXIoKTtcbiAgfVxuICByZXR1cm4gZ2V0Q29udGFpbmVyO1xufTtcbnZhciBQb3J0YWwgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICB2YXIgb3BlbiA9IHByb3BzLm9wZW4sXG4gICAgYXV0b0xvY2sgPSBwcm9wcy5hdXRvTG9jayxcbiAgICBnZXRDb250YWluZXIgPSBwcm9wcy5nZXRDb250YWluZXIsXG4gICAgZGVidWcgPSBwcm9wcy5kZWJ1ZyxcbiAgICBfcHJvcHMkYXV0b0Rlc3Ryb3kgPSBwcm9wcy5hdXRvRGVzdHJveSxcbiAgICBhdXRvRGVzdHJveSA9IF9wcm9wcyRhdXRvRGVzdHJveSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRhdXRvRGVzdHJveSxcbiAgICBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuO1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUob3BlbiksXG4gICAgX1JlYWN0JHVzZVN0YXRlMiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZSwgMiksXG4gICAgc2hvdWxkUmVuZGVyID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRTaG91bGRSZW5kZXIgPSBfUmVhY3QkdXNlU3RhdGUyWzFdO1xuICB2YXIgbWVyZ2VkUmVuZGVyID0gc2hvdWxkUmVuZGVyIHx8IG9wZW47XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBXYXJuaW5nID09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICB3YXJuaW5nKGNhblVzZURvbSgpIHx8ICFvcGVuLCBcIlBvcnRhbCBvbmx5IHdvcmsgaW4gY2xpZW50IHNpZGUuIFBsZWFzZSBjYWxsICd1c2VFZmZlY3QnIHRvIHNob3cgUG9ydGFsIGluc3RlYWQgZGVmYXVsdCByZW5kZXIgaW4gU1NSLlwiKTtcbiAgfVxuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT0gU2hvdWxkIFJlbmRlciA9PT09PT09PT09PT09PT09PT09PT09XG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKGF1dG9EZXN0cm95IHx8IG9wZW4pIHtcbiAgICAgIHNldFNob3VsZFJlbmRlcihvcGVuKTtcbiAgICB9XG4gIH0sIFtvcGVuLCBhdXRvRGVzdHJveV0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PSBDb250YWluZXIgPT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBfUmVhY3QkdXNlU3RhdGUzID0gUmVhY3QudXNlU3RhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGdldFBvcnRhbENvbnRhaW5lcihnZXRDb250YWluZXIpO1xuICAgIH0pLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTQgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUzLCAyKSxcbiAgICBpbm5lckNvbnRhaW5lciA9IF9SZWFjdCR1c2VTdGF0ZTRbMF0sXG4gICAgc2V0SW5uZXJDb250YWluZXIgPSBfUmVhY3QkdXNlU3RhdGU0WzFdO1xuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjdXN0b21pemVDb250YWluZXIgPSBnZXRQb3J0YWxDb250YWluZXIoZ2V0Q29udGFpbmVyKTtcblxuICAgIC8vIFRlbGwgY29tcG9uZW50IHRoYXQgd2UgY2hlY2sgdGhpcyBpbiBlZmZlY3Qgd2hpY2ggaXMgc2FmZSB0byBiZSBgbnVsbGBcbiAgICBzZXRJbm5lckNvbnRhaW5lcihjdXN0b21pemVDb250YWluZXIgIT09IG51bGwgJiYgY3VzdG9taXplQ29udGFpbmVyICE9PSB2b2lkIDAgPyBjdXN0b21pemVDb250YWluZXIgOiBudWxsKTtcbiAgfSk7XG4gIHZhciBfdXNlRG9tID0gdXNlRG9tKG1lcmdlZFJlbmRlciAmJiAhaW5uZXJDb250YWluZXIsIGRlYnVnKSxcbiAgICBfdXNlRG9tMiA9IF9zbGljZWRUb0FycmF5KF91c2VEb20sIDIpLFxuICAgIGRlZmF1bHRDb250YWluZXIgPSBfdXNlRG9tMlswXSxcbiAgICBxdWV1ZUNyZWF0ZSA9IF91c2VEb20yWzFdO1xuICB2YXIgbWVyZ2VkQ29udGFpbmVyID0gaW5uZXJDb250YWluZXIgIT09IG51bGwgJiYgaW5uZXJDb250YWluZXIgIT09IHZvaWQgMCA/IGlubmVyQ29udGFpbmVyIDogZGVmYXVsdENvbnRhaW5lcjtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09IExvY2tlciA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB1c2VTY3JvbGxMb2NrZXIoYXV0b0xvY2sgJiYgb3BlbiAmJiBjYW5Vc2VEb20oKSAmJiAobWVyZ2VkQ29udGFpbmVyID09PSBkZWZhdWx0Q29udGFpbmVyIHx8IG1lcmdlZENvbnRhaW5lciA9PT0gZG9jdW1lbnQuYm9keSkpO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZWYgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBjaGlsZFJlZiA9IG51bGw7XG4gIGlmIChjaGlsZHJlbiAmJiBzdXBwb3J0UmVmKGNoaWxkcmVuKSAmJiByZWYpIHtcbiAgICB2YXIgX3JlZiA9IGNoaWxkcmVuO1xuICAgIGNoaWxkUmVmID0gX3JlZi5yZWY7XG4gIH1cbiAgdmFyIG1lcmdlZFJlZiA9IHVzZUNvbXBvc2VSZWYoY2hpbGRSZWYsIHJlZik7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgLy8gRG8gbm90IHJlbmRlciB3aGVuIG5vdGhpbmcgbmVlZCByZW5kZXJcbiAgLy8gV2hlbiBpbm5lckNvbnRhaW5lciBpcyBgdW5kZWZpbmVkYCwgaXQgbWF5IG5vdCByZWFkeSBzaW5jZSB1c2VyIHVzZSByZWYgaW4gdGhlIHNhbWUgcmVuZGVyXG4gIGlmICghbWVyZ2VkUmVuZGVyIHx8ICFjYW5Vc2VEb20oKSB8fCBpbm5lckNvbnRhaW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBSZW5kZXIgaW5saW5lXG4gIHZhciByZW5kZXJJbmxpbmUgPSBtZXJnZWRDb250YWluZXIgPT09IGZhbHNlIHx8IGlubGluZU1vY2soKTtcbiAgdmFyIHJlZmZlZENoaWxkcmVuID0gY2hpbGRyZW47XG4gIGlmIChyZWYpIHtcbiAgICByZWZmZWRDaGlsZHJlbiA9IC8qI19fUFVSRV9fKi9SZWFjdC5jbG9uZUVsZW1lbnQoY2hpbGRyZW4sIHtcbiAgICAgIHJlZjogbWVyZ2VkUmVmXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE9yZGVyQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBxdWV1ZUNyZWF0ZVxuICB9LCByZW5kZXJJbmxpbmUgPyByZWZmZWRDaGlsZHJlbiA6IC8qI19fUFVSRV9fKi9jcmVhdGVQb3J0YWwocmVmZmVkQ2hpbGRyZW4sIG1lcmdlZENvbnRhaW5lcikpO1xufSk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBQb3J0YWwuZGlzcGxheU5hbWUgPSAnUG9ydGFsJztcbn1cbmV4cG9ydCBkZWZhdWx0IFBvcnRhbDsiLCJpbXBvcnQgUG9ydGFsIGZyb20gXCIuL1BvcnRhbFwiO1xuaW1wb3J0IHsgaW5saW5lTW9jayB9IGZyb20gXCIuL21vY2tcIjtcbmV4cG9ydCB7IGlubGluZU1vY2sgfTtcbmV4cG9ydCBkZWZhdWx0IFBvcnRhbDsiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgaXNGcmFnbWVudCB9IGZyb20gJ3JlYWN0LWlzJztcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRvQXJyYXkoY2hpbGRyZW4pIHtcbiAgdmFyIG9wdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG4gIHZhciByZXQgPSBbXTtcbiAgUmVhY3QuQ2hpbGRyZW4uZm9yRWFjaChjaGlsZHJlbiwgZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgaWYgKChjaGlsZCA9PT0gdW5kZWZpbmVkIHx8IGNoaWxkID09PSBudWxsKSAmJiAhb3B0aW9uLmtlZXBFbXB0eSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHtcbiAgICAgIHJldCA9IHJldC5jb25jYXQodG9BcnJheShjaGlsZCkpO1xuICAgIH0gZWxzZSBpZiAoaXNGcmFnbWVudChjaGlsZCkgJiYgY2hpbGQucHJvcHMpIHtcbiAgICAgIHJldCA9IHJldC5jb25jYXQodG9BcnJheShjaGlsZC5wcm9wcy5jaGlsZHJlbiwgb3B0aW9uKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldC5wdXNoKGNoaWxkKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmV0O1xufSIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUmVhY3RET00gZnJvbSAncmVhY3QtZG9tJztcbmV4cG9ydCBmdW5jdGlvbiBpc0RPTShub2RlKSB7XG4gIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50XG4gIC8vIFNpbmNlIFhVTEVsZW1lbnQgaXMgYWxzbyBzdWJjbGFzcyBvZiBFbGVtZW50LCB3ZSBvbmx5IG5lZWQgSFRNTEVsZW1lbnQgYW5kIFNWR0VsZW1lbnRcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgU1ZHRWxlbWVudDtcbn1cblxuLyoqXG4gKiBSZXR1cm4gaWYgYSBub2RlIGlzIGEgRE9NIG5vZGUuIEVsc2Ugd2lsbCByZXR1cm4gYnkgYGZpbmRET01Ob2RlYFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBmaW5kRE9NTm9kZShub2RlKSB7XG4gIGlmIChpc0RPTShub2RlKSkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG4gIGlmIChub2RlIGluc3RhbmNlb2YgUmVhY3QuQ29tcG9uZW50KSB7XG4gICAgcmV0dXJuIFJlYWN0RE9NLmZpbmRET01Ob2RlKG5vZGUpO1xuICB9XG4gIHJldHVybiBudWxsO1xufSIsIi8qKlxyXG4gKiBBIGNvbGxlY3Rpb24gb2Ygc2hpbXMgdGhhdCBwcm92aWRlIG1pbmltYWwgZnVuY3Rpb25hbGl0eSBvZiB0aGUgRVM2IGNvbGxlY3Rpb25zLlxyXG4gKlxyXG4gKiBUaGVzZSBpbXBsZW1lbnRhdGlvbnMgYXJlIG5vdCBtZWFudCB0byBiZSB1c2VkIG91dHNpZGUgb2YgdGhlIFJlc2l6ZU9ic2VydmVyXHJcbiAqIG1vZHVsZXMgYXMgdGhleSBjb3ZlciBvbmx5IGEgbGltaXRlZCByYW5nZSBvZiB1c2UgY2FzZXMuXHJcbiAqL1xyXG4vKiBlc2xpbnQtZGlzYWJsZSByZXF1aXJlLWpzZG9jLCB2YWxpZC1qc2RvYyAqL1xyXG52YXIgTWFwU2hpbSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodHlwZW9mIE1hcCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICByZXR1cm4gTWFwO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGluZGV4IGluIHByb3ZpZGVkIGFycmF5IHRoYXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGtleS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0FycmF5PEFycmF5Pn0gYXJyXHJcbiAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0SW5kZXgoYXJyLCBrZXkpIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gLTE7XHJcbiAgICAgICAgYXJyLnNvbWUoZnVuY3Rpb24gKGVudHJ5LCBpbmRleCkge1xyXG4gICAgICAgICAgICBpZiAoZW50cnlbMF0gPT09IGtleSkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gaW5kZXg7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgIH1cclxuICAgIHJldHVybiAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZnVuY3Rpb24gY2xhc3NfMSgpIHtcclxuICAgICAgICAgICAgdGhpcy5fX2VudHJpZXNfXyA9IFtdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2xhc3NfMS5wcm90b3R5cGUsIFwic2l6ZVwiLCB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX19lbnRyaWVzX18ubGVuZ3RoO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICAgICAqIEByZXR1cm5zIHsqfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXgodGhpcy5fX2VudHJpZXNfXywga2V5KTtcclxuICAgICAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fX2VudHJpZXNfX1tpbmRleF07XHJcbiAgICAgICAgICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeVsxXTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwYXJhbSB7Kn0ga2V5XHJcbiAgICAgICAgICogQHBhcmFtIHsqfSB2YWx1ZVxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNsYXNzXzEucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGdldEluZGV4KHRoaXMuX19lbnRyaWVzX18sIGtleSk7XHJcbiAgICAgICAgICAgIGlmICh+aW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX19lbnRyaWVzX19baW5kZXhdWzFdID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9fZW50cmllc19fLnB1c2goW2tleSwgdmFsdWVdKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5kZWxldGUgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIHZhciBlbnRyaWVzID0gdGhpcy5fX2VudHJpZXNfXztcclxuICAgICAgICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXgoZW50cmllcywga2V5KTtcclxuICAgICAgICAgICAgaWYgKH5pbmRleCkge1xyXG4gICAgICAgICAgICAgICAgZW50cmllcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcGFyYW0geyp9IGtleVxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgcmV0dXJuICEhfmdldEluZGV4KHRoaXMuX19lbnRyaWVzX18sIGtleSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAgICAgKi9cclxuICAgICAgICBjbGFzc18xLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5fX2VudHJpZXNfXy5zcGxpY2UoMCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xyXG4gICAgICAgICAqIEBwYXJhbSB7Kn0gW2N0eD1udWxsXVxyXG4gICAgICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGNsYXNzXzEucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiAoY2FsbGJhY2ssIGN0eCkge1xyXG4gICAgICAgICAgICBpZiAoY3R4ID09PSB2b2lkIDApIHsgY3R4ID0gbnVsbDsgfVxyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5fX2VudHJpZXNfXzsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBlbnRyeSA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoY3R4LCBlbnRyeVsxXSwgZW50cnlbMF0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gY2xhc3NfMTtcclxuICAgIH0oKSk7XHJcbn0pKCk7XG5cbi8qKlxyXG4gKiBEZXRlY3RzIHdoZXRoZXIgd2luZG93IGFuZCBkb2N1bWVudCBvYmplY3RzIGFyZSBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudC5cclxuICovXHJcbnZhciBpc0Jyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5kb2N1bWVudCA9PT0gZG9jdW1lbnQ7XG5cbi8vIFJldHVybnMgZ2xvYmFsIG9iamVjdCBvZiBhIGN1cnJlbnQgZW52aXJvbm1lbnQuXHJcbnZhciBnbG9iYWwkMSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2xvYmFsLk1hdGggPT09IE1hdGgpIHtcclxuICAgICAgICByZXR1cm4gZ2xvYmFsO1xyXG4gICAgfVxyXG4gICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmLk1hdGggPT09IE1hdGgpIHtcclxuICAgICAgICByZXR1cm4gc2VsZjtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PT0gTWF0aCkge1xyXG4gICAgICAgIHJldHVybiB3aW5kb3c7XHJcbiAgICB9XHJcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmV3LWZ1bmNcclxuICAgIHJldHVybiBGdW5jdGlvbigncmV0dXJuIHRoaXMnKSgpO1xyXG59KSgpO1xuXG4vKipcclxuICogQSBzaGltIGZvciB0aGUgcmVxdWVzdEFuaW1hdGlvbkZyYW1lIHdoaWNoIGZhbGxzIGJhY2sgdG8gdGhlIHNldFRpbWVvdXQgaWZcclxuICogZmlyc3Qgb25lIGlzIG5vdCBzdXBwb3J0ZWQuXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJlcXVlc3RzJyBpZGVudGlmaWVyLlxyXG4gKi9cclxudmFyIHJlcXVlc3RBbmltYXRpb25GcmFtZSQxID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGlmICh0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgLy8gSXQncyByZXF1aXJlZCB0byB1c2UgYSBib3VuZGVkIGZ1bmN0aW9uIGJlY2F1c2UgSUUgc29tZXRpbWVzIHRocm93c1xyXG4gICAgICAgIC8vIGFuIFwiSW52YWxpZCBjYWxsaW5nIG9iamVjdFwiIGVycm9yIGlmIHJBRiBpcyBpbnZva2VkIHdpdGhvdXQgdGhlIGdsb2JhbFxyXG4gICAgICAgIC8vIG9iamVjdCBvbiB0aGUgbGVmdCBoYW5kIHNpZGUuXHJcbiAgICAgICAgcmV0dXJuIHJlcXVlc3RBbmltYXRpb25GcmFtZS5iaW5kKGdsb2JhbCQxKTtcclxuICAgIH1cclxuICAgIHJldHVybiBmdW5jdGlvbiAoY2FsbGJhY2spIHsgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gY2FsbGJhY2soRGF0ZS5ub3coKSk7IH0sIDEwMDAgLyA2MCk7IH07XHJcbn0pKCk7XG5cbi8vIERlZmluZXMgbWluaW11bSB0aW1lb3V0IGJlZm9yZSBhZGRpbmcgYSB0cmFpbGluZyBjYWxsLlxyXG52YXIgdHJhaWxpbmdUaW1lb3V0ID0gMjtcclxuLyoqXHJcbiAqIENyZWF0ZXMgYSB3cmFwcGVyIGZ1bmN0aW9uIHdoaWNoIGVuc3VyZXMgdGhhdCBwcm92aWRlZCBjYWxsYmFjayB3aWxsIGJlXHJcbiAqIGludm9rZWQgb25seSBvbmNlIGR1cmluZyB0aGUgc3BlY2lmaWVkIGRlbGF5IHBlcmlvZC5cclxuICpcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBiZSBpbnZva2VkIGFmdGVyIHRoZSBkZWxheSBwZXJpb2QuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWxheSAtIERlbGF5IGFmdGVyIHdoaWNoIHRvIGludm9rZSBjYWxsYmFjay5cclxuICogQHJldHVybnMge0Z1bmN0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gdGhyb3R0bGUgKGNhbGxiYWNrLCBkZWxheSkge1xyXG4gICAgdmFyIGxlYWRpbmdDYWxsID0gZmFsc2UsIHRyYWlsaW5nQ2FsbCA9IGZhbHNlLCBsYXN0Q2FsbFRpbWUgPSAwO1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2VzIHRoZSBvcmlnaW5hbCBjYWxsYmFjayBmdW5jdGlvbiBhbmQgc2NoZWR1bGVzIG5ldyBpbnZvY2F0aW9uIGlmXHJcbiAgICAgKiB0aGUgXCJwcm94eVwiIHdhcyBjYWxsZWQgZHVyaW5nIGN1cnJlbnQgcmVxdWVzdC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gcmVzb2x2ZVBlbmRpbmcoKSB7XHJcbiAgICAgICAgaWYgKGxlYWRpbmdDYWxsKSB7XHJcbiAgICAgICAgICAgIGxlYWRpbmdDYWxsID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0cmFpbGluZ0NhbGwpIHtcclxuICAgICAgICAgICAgcHJveHkoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIGludm9rZWQgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkZWxheS4gSXQgd2lsbCBmdXJ0aGVyIHBvc3Rwb25lXHJcbiAgICAgKiBpbnZvY2F0aW9uIG9mIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBkZWxlZ2F0aW5nIGl0IHRvIHRoZVxyXG4gICAgICogcmVxdWVzdEFuaW1hdGlvbkZyYW1lLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiB0aW1lb3V0Q2FsbGJhY2soKSB7XHJcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lJDEocmVzb2x2ZVBlbmRpbmcpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBTY2hlZHVsZXMgaW52b2NhdGlvbiBvZiB0aGUgb3JpZ2luYWwgZnVuY3Rpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHByb3h5KCkge1xyXG4gICAgICAgIHZhciB0aW1lU3RhbXAgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgIGlmIChsZWFkaW5nQ2FsbCkge1xyXG4gICAgICAgICAgICAvLyBSZWplY3QgaW1tZWRpYXRlbHkgZm9sbG93aW5nIGNhbGxzLlxyXG4gICAgICAgICAgICBpZiAodGltZVN0YW1wIC0gbGFzdENhbGxUaW1lIDwgdHJhaWxpbmdUaW1lb3V0KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gU2NoZWR1bGUgbmV3IGNhbGwgdG8gYmUgaW4gaW52b2tlZCB3aGVuIHRoZSBwZW5kaW5nIG9uZSBpcyByZXNvbHZlZC5cclxuICAgICAgICAgICAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIFwidHJhbnNpdGlvbnNcIiB3aGljaCBuZXZlciBhY3R1YWxseSBzdGFydFxyXG4gICAgICAgICAgICAvLyBpbW1lZGlhdGVseSBzbyB0aGVyZSBpcyBhIGNoYW5jZSB0aGF0IHdlIG1pZ2h0IG1pc3Mgb25lIGlmIGNoYW5nZVxyXG4gICAgICAgICAgICAvLyBoYXBwZW5zIGFtaWRzIHRoZSBwZW5kaW5nIGludm9jYXRpb24uXHJcbiAgICAgICAgICAgIHRyYWlsaW5nQ2FsbCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBsZWFkaW5nQ2FsbCA9IHRydWU7XHJcbiAgICAgICAgICAgIHRyYWlsaW5nQ2FsbCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KHRpbWVvdXRDYWxsYmFjaywgZGVsYXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsYXN0Q2FsbFRpbWUgPSB0aW1lU3RhbXA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcHJveHk7XHJcbn1cblxuLy8gTWluaW11bSBkZWxheSBiZWZvcmUgaW52b2tpbmcgdGhlIHVwZGF0ZSBvZiBvYnNlcnZlcnMuXHJcbnZhciBSRUZSRVNIX0RFTEFZID0gMjA7XHJcbi8vIEEgbGlzdCBvZiBzdWJzdHJpbmdzIG9mIENTUyBwcm9wZXJ0aWVzIHVzZWQgdG8gZmluZCB0cmFuc2l0aW9uIGV2ZW50cyB0aGF0XHJcbi8vIG1pZ2h0IGFmZmVjdCBkaW1lbnNpb25zIG9mIG9ic2VydmVkIGVsZW1lbnRzLlxyXG52YXIgdHJhbnNpdGlvbktleXMgPSBbJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCcsICd3aWR0aCcsICdoZWlnaHQnLCAnc2l6ZScsICd3ZWlnaHQnXTtcclxuLy8gQ2hlY2sgaWYgTXV0YXRpb25PYnNlcnZlciBpcyBhdmFpbGFibGUuXHJcbnZhciBtdXRhdGlvbk9ic2VydmVyU3VwcG9ydGVkID0gdHlwZW9mIE11dGF0aW9uT2JzZXJ2ZXIgIT09ICd1bmRlZmluZWQnO1xyXG4vKipcclxuICogU2luZ2xldG9uIGNvbnRyb2xsZXIgY2xhc3Mgd2hpY2ggaGFuZGxlcyB1cGRhdGVzIG9mIFJlc2l6ZU9ic2VydmVyIGluc3RhbmNlcy5cclxuICovXHJcbnZhciBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlcigpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciBET00gbGlzdGVuZXJzIGhhdmUgYmVlbiBhZGRlZC5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtib29sZWFufVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY29ubmVjdGVkXyA9IGZhbHNlO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFRlbGxzIHRoYXQgY29udHJvbGxlciBoYXMgc3Vic2NyaWJlZCBmb3IgTXV0YXRpb24gRXZlbnRzLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGUge2Jvb2xlYW59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXyA9IGZhbHNlO1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEtlZXBzIHJlZmVyZW5jZSB0byB0aGUgaW5zdGFuY2Ugb2YgTXV0YXRpb25PYnNlcnZlci5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtNdXRhdGlvbk9ic2VydmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfID0gbnVsbDtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBIGxpc3Qgb2YgY29ubmVjdGVkIG9ic2VydmVycy5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEBwcml2YXRlIHtBcnJheTxSZXNpemVPYnNlcnZlclNQST59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5vYnNlcnZlcnNfID0gW107XHJcbiAgICAgICAgdGhpcy5vblRyYW5zaXRpb25FbmRfID0gdGhpcy5vblRyYW5zaXRpb25FbmRfLmJpbmQodGhpcyk7XHJcbiAgICAgICAgdGhpcy5yZWZyZXNoID0gdGhyb3R0bGUodGhpcy5yZWZyZXNoLmJpbmQodGhpcyksIFJFRlJFU0hfREVMQVkpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIG9ic2VydmVyIHRvIG9ic2VydmVycyBsaXN0LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJTUEl9IG9ic2VydmVyIC0gT2JzZXJ2ZXIgdG8gYmUgYWRkZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS5hZGRPYnNlcnZlciA9IGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgIGlmICghfnRoaXMub2JzZXJ2ZXJzXy5pbmRleE9mKG9ic2VydmVyKSkge1xyXG4gICAgICAgICAgICB0aGlzLm9ic2VydmVyc18ucHVzaChvYnNlcnZlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEFkZCBsaXN0ZW5lcnMgaWYgdGhleSBoYXZlbid0IGJlZW4gYWRkZWQgeWV0LlxyXG4gICAgICAgIGlmICghdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29ubmVjdF8oKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIG9ic2VydmVyIGZyb20gb2JzZXJ2ZXJzIGxpc3QuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtSZXNpemVPYnNlcnZlclNQSX0gb2JzZXJ2ZXIgLSBPYnNlcnZlciB0byBiZSByZW1vdmVkLlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUucmVtb3ZlT2JzZXJ2ZXIgPSBmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICB2YXIgb2JzZXJ2ZXJzID0gdGhpcy5vYnNlcnZlcnNfO1xyXG4gICAgICAgIHZhciBpbmRleCA9IG9ic2VydmVycy5pbmRleE9mKG9ic2VydmVyKTtcclxuICAgICAgICAvLyBSZW1vdmUgb2JzZXJ2ZXIgaWYgaXQncyBwcmVzZW50IGluIHJlZ2lzdHJ5LlxyXG4gICAgICAgIGlmICh+aW5kZXgpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFJlbW92ZSBsaXN0ZW5lcnMgaWYgY29udHJvbGxlciBoYXMgbm8gY29ubmVjdGVkIG9ic2VydmVycy5cclxuICAgICAgICBpZiAoIW9ic2VydmVycy5sZW5ndGggJiYgdGhpcy5jb25uZWN0ZWRfKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGlzY29ubmVjdF8oKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2VzIHRoZSB1cGRhdGUgb2Ygb2JzZXJ2ZXJzLiBJdCB3aWxsIGNvbnRpbnVlIHJ1bm5pbmcgdXBkYXRlcyBpbnNvZmFyXHJcbiAgICAgKiBpdCBkZXRlY3RzIGNoYW5nZXMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgY2hhbmdlc0RldGVjdGVkID0gdGhpcy51cGRhdGVPYnNlcnZlcnNfKCk7XHJcbiAgICAgICAgLy8gQ29udGludWUgcnVubmluZyB1cGRhdGVzIGlmIGNoYW5nZXMgaGF2ZSBiZWVuIGRldGVjdGVkIGFzIHRoZXJlIG1pZ2h0XHJcbiAgICAgICAgLy8gYmUgZnV0dXJlIG9uZXMgY2F1c2VkIGJ5IENTUyB0cmFuc2l0aW9ucy5cclxuICAgICAgICBpZiAoY2hhbmdlc0RldGVjdGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFVwZGF0ZXMgZXZlcnkgb2JzZXJ2ZXIgZnJvbSBvYnNlcnZlcnMgbGlzdCBhbmQgbm90aWZpZXMgdGhlbSBvZiBxdWV1ZWRcclxuICAgICAqIGVudHJpZXMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIFwidHJ1ZVwiIGlmIGFueSBvYnNlcnZlciBoYXMgZGV0ZWN0ZWQgY2hhbmdlcyBpblxyXG4gICAgICogICAgICBkaW1lbnNpb25zIG9mIGl0J3MgZWxlbWVudHMuXHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5wcm90b3R5cGUudXBkYXRlT2JzZXJ2ZXJzXyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBDb2xsZWN0IG9ic2VydmVycyB0aGF0IGhhdmUgYWN0aXZlIG9ic2VydmF0aW9ucy5cclxuICAgICAgICB2YXIgYWN0aXZlT2JzZXJ2ZXJzID0gdGhpcy5vYnNlcnZlcnNfLmZpbHRlcihmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmVyLmdhdGhlckFjdGl2ZSgpLCBvYnNlcnZlci5oYXNBY3RpdmUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBEZWxpdmVyIG5vdGlmaWNhdGlvbnMgaW4gYSBzZXBhcmF0ZSBjeWNsZSBpbiBvcmRlciB0byBhdm9pZCBhbnlcclxuICAgICAgICAvLyBjb2xsaXNpb25zIGJldHdlZW4gb2JzZXJ2ZXJzLCBlLmcuIHdoZW4gbXVsdGlwbGUgaW5zdGFuY2VzIG9mXHJcbiAgICAgICAgLy8gUmVzaXplT2JzZXJ2ZXIgYXJlIHRyYWNraW5nIHRoZSBzYW1lIGVsZW1lbnQgYW5kIHRoZSBjYWxsYmFjayBvZiBvbmVcclxuICAgICAgICAvLyBvZiB0aGVtIGNoYW5nZXMgY29udGVudCBkaW1lbnNpb25zIG9mIHRoZSBvYnNlcnZlZCB0YXJnZXQuIFNvbWV0aW1lc1xyXG4gICAgICAgIC8vIHRoaXMgbWF5IHJlc3VsdCBpbiBub3RpZmljYXRpb25zIGJlaW5nIGJsb2NrZWQgZm9yIHRoZSByZXN0IG9mIG9ic2VydmVycy5cclxuICAgICAgICBhY3RpdmVPYnNlcnZlcnMuZm9yRWFjaChmdW5jdGlvbiAob2JzZXJ2ZXIpIHsgcmV0dXJuIG9ic2VydmVyLmJyb2FkY2FzdEFjdGl2ZSgpOyB9KTtcclxuICAgICAgICByZXR1cm4gYWN0aXZlT2JzZXJ2ZXJzLmxlbmd0aCA+IDA7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBJbml0aWFsaXplcyBET00gbGlzdGVuZXJzLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLnByb3RvdHlwZS5jb25uZWN0XyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBEbyBub3RoaW5nIGlmIHJ1bm5pbmcgaW4gYSBub24tYnJvd3NlciBlbnZpcm9ubWVudCBvciBpZiBsaXN0ZW5lcnNcclxuICAgICAgICAvLyBoYXZlIGJlZW4gYWxyZWFkeSBhZGRlZC5cclxuICAgICAgICBpZiAoIWlzQnJvd3NlciB8fCB0aGlzLmNvbm5lY3RlZF8pIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTdWJzY3JpcHRpb24gdG8gdGhlIFwiVHJhbnNpdGlvbmVuZFwiIGV2ZW50IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGZvclxyXG4gICAgICAgIC8vIGRlbGF5ZWQgdHJhbnNpdGlvbnMuIFRoaXMgd2F5IGl0J3MgcG9zc2libGUgdG8gY2FwdHVyZSBhdCBsZWFzdCB0aGVcclxuICAgICAgICAvLyBmaW5hbCBzdGF0ZSBvZiBhbiBlbGVtZW50LlxyXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCB0aGlzLm9uVHJhbnNpdGlvbkVuZF8pO1xyXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnJlZnJlc2gpO1xyXG4gICAgICAgIGlmIChtdXRhdGlvbk9ic2VydmVyU3VwcG9ydGVkKSB7XHJcbiAgICAgICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIodGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgdGhpcy5tdXRhdGlvbnNPYnNlcnZlcl8ub2JzZXJ2ZShkb2N1bWVudCwge1xyXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNoYXJhY3RlckRhdGE6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBzdWJ0cmVlOiB0cnVlXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NU3VidHJlZU1vZGlmaWVkJywgdGhpcy5yZWZyZXNoKTtcclxuICAgICAgICAgICAgdGhpcy5tdXRhdGlvbkV2ZW50c0FkZGVkXyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29ubmVjdGVkXyA9IHRydWU7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIERPTSBsaXN0ZW5lcnMuXHJcbiAgICAgKlxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLmRpc2Nvbm5lY3RfID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgcnVubmluZyBpbiBhIG5vbi1icm93c2VyIGVudmlyb25tZW50IG9yIGlmIGxpc3RlbmVyc1xyXG4gICAgICAgIC8vIGhhdmUgYmVlbiBhbHJlYWR5IHJlbW92ZWQuXHJcbiAgICAgICAgaWYgKCFpc0Jyb3dzZXIgfHwgIXRoaXMuY29ubmVjdGVkXykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCB0aGlzLm9uVHJhbnNpdGlvbkVuZF8pO1xyXG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnJlZnJlc2gpO1xyXG4gICAgICAgIGlmICh0aGlzLm11dGF0aW9uc09ic2VydmVyXykge1xyXG4gICAgICAgICAgICB0aGlzLm11dGF0aW9uc09ic2VydmVyXy5kaXNjb25uZWN0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLm11dGF0aW9uRXZlbnRzQWRkZWRfKSB7XHJcbiAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ0RPTVN1YnRyZWVNb2RpZmllZCcsIHRoaXMucmVmcmVzaCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubXV0YXRpb25zT2JzZXJ2ZXJfID0gbnVsbDtcclxuICAgICAgICB0aGlzLm11dGF0aW9uRXZlbnRzQWRkZWRfID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jb25uZWN0ZWRfID0gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBcIlRyYW5zaXRpb25lbmRcIiBldmVudCBoYW5kbGVyLlxyXG4gICAgICpcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAcGFyYW0ge1RyYW5zaXRpb25FdmVudH0gZXZlbnRcclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIucHJvdG90eXBlLm9uVHJhbnNpdGlvbkVuZF8gPSBmdW5jdGlvbiAoX2EpIHtcclxuICAgICAgICB2YXIgX2IgPSBfYS5wcm9wZXJ0eU5hbWUsIHByb3BlcnR5TmFtZSA9IF9iID09PSB2b2lkIDAgPyAnJyA6IF9iO1xyXG4gICAgICAgIC8vIERldGVjdCB3aGV0aGVyIHRyYW5zaXRpb24gbWF5IGFmZmVjdCBkaW1lbnNpb25zIG9mIGFuIGVsZW1lbnQuXHJcbiAgICAgICAgdmFyIGlzUmVmbG93UHJvcGVydHkgPSB0cmFuc2l0aW9uS2V5cy5zb21lKGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgcmV0dXJuICEhfnByb3BlcnR5TmFtZS5pbmRleE9mKGtleSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKGlzUmVmbG93UHJvcGVydHkpIHtcclxuICAgICAgICAgICAgdGhpcy5yZWZyZXNoKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBpbnN0YW5jZSBvZiB0aGUgUmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtSZXNpemVPYnNlcnZlckNvbnRyb2xsZXJ9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlci5nZXRJbnN0YW5jZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaW5zdGFuY2VfKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaW5zdGFuY2VfID0gbmV3IFJlc2l6ZU9ic2VydmVyQ29udHJvbGxlcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZV87XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBIb2xkcyByZWZlcmVuY2UgdG8gdGhlIGNvbnRyb2xsZXIncyBpbnN0YW5jZS5cclxuICAgICAqXHJcbiAgICAgKiBAcHJpdmF0ZSB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIuaW5zdGFuY2VfID0gbnVsbDtcclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXI7XHJcbn0oKSk7XG5cbi8qKlxyXG4gKiBEZWZpbmVzIG5vbi13cml0YWJsZS9lbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgdGhlIHByb3ZpZGVkIHRhcmdldCBvYmplY3QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXQgLSBPYmplY3QgZm9yIHdoaWNoIHRvIGRlZmluZSBwcm9wZXJ0aWVzLlxyXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcHMgLSBQcm9wZXJ0aWVzIHRvIGJlIGRlZmluZWQuXHJcbiAqIEByZXR1cm5zIHtPYmplY3R9IFRhcmdldCBvYmplY3QuXHJcbiAqL1xyXG52YXIgZGVmaW5lQ29uZmlndXJhYmxlID0gKGZ1bmN0aW9uICh0YXJnZXQsIHByb3BzKSB7XHJcbiAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gT2JqZWN0LmtleXMocHJvcHMpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgIHZhciBrZXkgPSBfYVtfaV07XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCB7XHJcbiAgICAgICAgICAgIHZhbHVlOiBwcm9wc1trZXldLFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcclxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxyXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiB0YXJnZXQ7XHJcbn0pO1xuXG4vKipcclxuICogUmV0dXJucyB0aGUgZ2xvYmFsIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggcHJvdmlkZWQgZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxyXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxyXG4gKi9cclxudmFyIGdldFdpbmRvd09mID0gKGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgIC8vIEFzc3VtZSB0aGF0IHRoZSBlbGVtZW50IGlzIGFuIGluc3RhbmNlIG9mIE5vZGUsIHdoaWNoIG1lYW5zIHRoYXQgaXRcclxuICAgIC8vIGhhcyB0aGUgXCJvd25lckRvY3VtZW50XCIgcHJvcGVydHkgZnJvbSB3aGljaCB3ZSBjYW4gcmV0cmlldmUgYVxyXG4gICAgLy8gY29ycmVzcG9uZGluZyBnbG9iYWwgb2JqZWN0LlxyXG4gICAgdmFyIG93bmVyR2xvYmFsID0gdGFyZ2V0ICYmIHRhcmdldC5vd25lckRvY3VtZW50ICYmIHRhcmdldC5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O1xyXG4gICAgLy8gUmV0dXJuIHRoZSBsb2NhbCBnbG9iYWwgb2JqZWN0IGlmIGl0J3Mgbm90IHBvc3NpYmxlIGV4dHJhY3Qgb25lIGZyb21cclxuICAgIC8vIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAgICByZXR1cm4gb3duZXJHbG9iYWwgfHwgZ2xvYmFsJDE7XHJcbn0pO1xuXG4vLyBQbGFjZWhvbGRlciBvZiBhbiBlbXB0eSBjb250ZW50IHJlY3RhbmdsZS5cclxudmFyIGVtcHR5UmVjdCA9IGNyZWF0ZVJlY3RJbml0KDAsIDAsIDAsIDApO1xyXG4vKipcclxuICogQ29udmVydHMgcHJvdmlkZWQgc3RyaW5nIHRvIGEgbnVtYmVyLlxyXG4gKlxyXG4gKiBAcGFyYW0ge251bWJlcnxzdHJpbmd9IHZhbHVlXHJcbiAqIEByZXR1cm5zIHtudW1iZXJ9XHJcbiAqL1xyXG5mdW5jdGlvbiB0b0Zsb2F0KHZhbHVlKSB7XHJcbiAgICByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSkgfHwgMDtcclxufVxyXG4vKipcclxuICogRXh0cmFjdHMgYm9yZGVycyBzaXplIGZyb20gcHJvdmlkZWQgc3R5bGVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0NTU1N0eWxlRGVjbGFyYXRpb259IHN0eWxlc1xyXG4gKiBAcGFyYW0gey4uLnN0cmluZ30gcG9zaXRpb25zIC0gQm9yZGVycyBwb3NpdGlvbnMgKHRvcCwgcmlnaHQsIC4uLilcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIGdldEJvcmRlcnNTaXplKHN0eWxlcykge1xyXG4gICAgdmFyIHBvc2l0aW9ucyA9IFtdO1xyXG4gICAgZm9yICh2YXIgX2kgPSAxOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICBwb3NpdGlvbnNbX2kgLSAxXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcG9zaXRpb25zLnJlZHVjZShmdW5jdGlvbiAoc2l6ZSwgcG9zaXRpb24pIHtcclxuICAgICAgICB2YXIgdmFsdWUgPSBzdHlsZXNbJ2JvcmRlci0nICsgcG9zaXRpb24gKyAnLXdpZHRoJ107XHJcbiAgICAgICAgcmV0dXJuIHNpemUgKyB0b0Zsb2F0KHZhbHVlKTtcclxuICAgIH0sIDApO1xyXG59XHJcbi8qKlxyXG4gKiBFeHRyYWN0cyBwYWRkaW5ncyBzaXplcyBmcm9tIHByb3ZpZGVkIHN0eWxlcy5cclxuICpcclxuICogQHBhcmFtIHtDU1NTdHlsZURlY2xhcmF0aW9ufSBzdHlsZXNcclxuICogQHJldHVybnMge09iamVjdH0gUGFkZGluZ3MgYm94LlxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UGFkZGluZ3Moc3R5bGVzKSB7XHJcbiAgICB2YXIgcG9zaXRpb25zID0gWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnXTtcclxuICAgIHZhciBwYWRkaW5ncyA9IHt9O1xyXG4gICAgZm9yICh2YXIgX2kgPSAwLCBwb3NpdGlvbnNfMSA9IHBvc2l0aW9uczsgX2kgPCBwb3NpdGlvbnNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICB2YXIgcG9zaXRpb24gPSBwb3NpdGlvbnNfMVtfaV07XHJcbiAgICAgICAgdmFyIHZhbHVlID0gc3R5bGVzWydwYWRkaW5nLScgKyBwb3NpdGlvbl07XHJcbiAgICAgICAgcGFkZGluZ3NbcG9zaXRpb25dID0gdG9GbG9hdCh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcGFkZGluZ3M7XHJcbn1cclxuLyoqXHJcbiAqIENhbGN1bGF0ZXMgY29udGVudCByZWN0YW5nbGUgb2YgcHJvdmlkZWQgU1ZHIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U1ZHR3JhcGhpY3NFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IGNvbnRlbnQgcmVjdGFuZ2xlIG9mIHdoaWNoIG5lZWRzXHJcbiAqICAgICAgdG8gYmUgY2FsY3VsYXRlZC5cclxuICogQHJldHVybnMge0RPTVJlY3RJbml0fVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0U1ZHQ29udGVudFJlY3QodGFyZ2V0KSB7XHJcbiAgICB2YXIgYmJveCA9IHRhcmdldC5nZXRCQm94KCk7XHJcbiAgICByZXR1cm4gY3JlYXRlUmVjdEluaXQoMCwgMCwgYmJveC53aWR0aCwgYmJveC5oZWlnaHQpO1xyXG59XHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIGNvbnRlbnQgcmVjdGFuZ2xlIG9mIHByb3ZpZGVkIEhUTUxFbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IGZvciB3aGljaCB0byBjYWxjdWxhdGUgdGhlIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gKiBAcmV0dXJucyB7RE9NUmVjdEluaXR9XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRIVE1MRWxlbWVudENvbnRlbnRSZWN0KHRhcmdldCkge1xyXG4gICAgLy8gQ2xpZW50IHdpZHRoICYgaGVpZ2h0IHByb3BlcnRpZXMgY2FuJ3QgYmVcclxuICAgIC8vIHVzZWQgZXhjbHVzaXZlbHkgYXMgdGhleSBwcm92aWRlIHJvdW5kZWQgdmFsdWVzLlxyXG4gICAgdmFyIGNsaWVudFdpZHRoID0gdGFyZ2V0LmNsaWVudFdpZHRoLCBjbGllbnRIZWlnaHQgPSB0YXJnZXQuY2xpZW50SGVpZ2h0O1xyXG4gICAgLy8gQnkgdGhpcyBjb25kaXRpb24gd2UgY2FuIGNhdGNoIGFsbCBub24tcmVwbGFjZWQgaW5saW5lLCBoaWRkZW4gYW5kXHJcbiAgICAvLyBkZXRhY2hlZCBlbGVtZW50cy4gVGhvdWdoIGVsZW1lbnRzIHdpdGggd2lkdGggJiBoZWlnaHQgcHJvcGVydGllcyBsZXNzXHJcbiAgICAvLyB0aGFuIDAuNSB3aWxsIGJlIGRpc2NhcmRlZCBhcyB3ZWxsLlxyXG4gICAgLy9cclxuICAgIC8vIFdpdGhvdXQgaXQgd2Ugd291bGQgbmVlZCB0byBpbXBsZW1lbnQgc2VwYXJhdGUgbWV0aG9kcyBmb3IgZWFjaCBvZlxyXG4gICAgLy8gdGhvc2UgY2FzZXMgYW5kIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHBlcmZvcm0gYSBwcmVjaXNlIGFuZCBwZXJmb3JtYW5jZVxyXG4gICAgLy8gZWZmZWN0aXZlIHRlc3QgZm9yIGhpZGRlbiBlbGVtZW50cy4gRS5nLiBldmVuIGpRdWVyeSdzICc6dmlzaWJsZScgZmlsdGVyXHJcbiAgICAvLyBnaXZlcyB3cm9uZyByZXN1bHRzIGZvciBlbGVtZW50cyB3aXRoIHdpZHRoICYgaGVpZ2h0IGxlc3MgdGhhbiAwLjUuXHJcbiAgICBpZiAoIWNsaWVudFdpZHRoICYmICFjbGllbnRIZWlnaHQpIHtcclxuICAgICAgICByZXR1cm4gZW1wdHlSZWN0O1xyXG4gICAgfVxyXG4gICAgdmFyIHN0eWxlcyA9IGdldFdpbmRvd09mKHRhcmdldCkuZ2V0Q29tcHV0ZWRTdHlsZSh0YXJnZXQpO1xyXG4gICAgdmFyIHBhZGRpbmdzID0gZ2V0UGFkZGluZ3Moc3R5bGVzKTtcclxuICAgIHZhciBob3JpelBhZCA9IHBhZGRpbmdzLmxlZnQgKyBwYWRkaW5ncy5yaWdodDtcclxuICAgIHZhciB2ZXJ0UGFkID0gcGFkZGluZ3MudG9wICsgcGFkZGluZ3MuYm90dG9tO1xyXG4gICAgLy8gQ29tcHV0ZWQgc3R5bGVzIG9mIHdpZHRoICYgaGVpZ2h0IGFyZSBiZWluZyB1c2VkIGJlY2F1c2UgdGhleSBhcmUgdGhlXHJcbiAgICAvLyBvbmx5IGRpbWVuc2lvbnMgYXZhaWxhYmxlIHRvIEpTIHRoYXQgY29udGFpbiBub24tcm91bmRlZCB2YWx1ZXMuIEl0IGNvdWxkXHJcbiAgICAvLyBiZSBwb3NzaWJsZSB0byB1dGlsaXplIHRoZSBnZXRCb3VuZGluZ0NsaWVudFJlY3QgaWYgb25seSBpdCdzIGRhdGEgd2Fzbid0XHJcbiAgICAvLyBhZmZlY3RlZCBieSBDU1MgdHJhbnNmb3JtYXRpb25zIGxldCBhbG9uZSBwYWRkaW5ncywgYm9yZGVycyBhbmQgc2Nyb2xsIGJhcnMuXHJcbiAgICB2YXIgd2lkdGggPSB0b0Zsb2F0KHN0eWxlcy53aWR0aCksIGhlaWdodCA9IHRvRmxvYXQoc3R5bGVzLmhlaWdodCk7XHJcbiAgICAvLyBXaWR0aCAmIGhlaWdodCBpbmNsdWRlIHBhZGRpbmdzIGFuZCBib3JkZXJzIHdoZW4gdGhlICdib3JkZXItYm94JyBib3hcclxuICAgIC8vIG1vZGVsIGlzIGFwcGxpZWQgKGV4Y2VwdCBmb3IgSUUpLlxyXG4gICAgaWYgKHN0eWxlcy5ib3hTaXppbmcgPT09ICdib3JkZXItYm94Jykge1xyXG4gICAgICAgIC8vIEZvbGxvd2luZyBjb25kaXRpb25zIGFyZSByZXF1aXJlZCB0byBoYW5kbGUgSW50ZXJuZXQgRXhwbG9yZXIgd2hpY2hcclxuICAgICAgICAvLyBkb2Vzbid0IGluY2x1ZGUgcGFkZGluZ3MgYW5kIGJvcmRlcnMgdG8gY29tcHV0ZWQgQ1NTIGRpbWVuc2lvbnMuXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBXZSBjYW4gc2F5IHRoYXQgaWYgQ1NTIGRpbWVuc2lvbnMgKyBwYWRkaW5ncyBhcmUgZXF1YWwgdG8gdGhlIFwiY2xpZW50XCJcclxuICAgICAgICAvLyBwcm9wZXJ0aWVzIHRoZW4gaXQncyBlaXRoZXIgSUUsIGFuZCB0aHVzIHdlIGRvbid0IG5lZWQgdG8gc3VidHJhY3RcclxuICAgICAgICAvLyBhbnl0aGluZywgb3IgYW4gZWxlbWVudCBtZXJlbHkgZG9lc24ndCBoYXZlIHBhZGRpbmdzL2JvcmRlcnMgc3R5bGVzLlxyXG4gICAgICAgIGlmIChNYXRoLnJvdW5kKHdpZHRoICsgaG9yaXpQYWQpICE9PSBjbGllbnRXaWR0aCkge1xyXG4gICAgICAgICAgICB3aWR0aCAtPSBnZXRCb3JkZXJzU2l6ZShzdHlsZXMsICdsZWZ0JywgJ3JpZ2h0JykgKyBob3JpelBhZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKE1hdGgucm91bmQoaGVpZ2h0ICsgdmVydFBhZCkgIT09IGNsaWVudEhlaWdodCkge1xyXG4gICAgICAgICAgICBoZWlnaHQgLT0gZ2V0Qm9yZGVyc1NpemUoc3R5bGVzLCAndG9wJywgJ2JvdHRvbScpICsgdmVydFBhZDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBGb2xsb3dpbmcgc3RlcHMgY2FuJ3QgYmUgYXBwbGllZCB0byB0aGUgZG9jdW1lbnQncyByb290IGVsZW1lbnQgYXMgaXRzXHJcbiAgICAvLyBjbGllbnRbV2lkdGgvSGVpZ2h0XSBwcm9wZXJ0aWVzIHJlcHJlc2VudCB2aWV3cG9ydCBhcmVhIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAvLyBCZXNpZGVzLCBpdCdzIGFzIHdlbGwgbm90IG5lY2Vzc2FyeSBhcyB0aGUgPGh0bWw+IGl0c2VsZiBuZWl0aGVyIGhhc1xyXG4gICAgLy8gcmVuZGVyZWQgc2Nyb2xsIGJhcnMgbm9yIGl0IGNhbiBiZSBjbGlwcGVkLlxyXG4gICAgaWYgKCFpc0RvY3VtZW50RWxlbWVudCh0YXJnZXQpKSB7XHJcbiAgICAgICAgLy8gSW4gc29tZSBicm93c2VycyAob25seSBpbiBGaXJlZm94LCBhY3R1YWxseSkgQ1NTIHdpZHRoICYgaGVpZ2h0XHJcbiAgICAgICAgLy8gaW5jbHVkZSBzY3JvbGwgYmFycyBzaXplIHdoaWNoIGNhbiBiZSByZW1vdmVkIGF0IHRoaXMgc3RlcCBhcyBzY3JvbGxcclxuICAgICAgICAvLyBiYXJzIGFyZSB0aGUgb25seSBkaWZmZXJlbmNlIGJldHdlZW4gcm91bmRlZCBkaW1lbnNpb25zICsgcGFkZGluZ3NcclxuICAgICAgICAvLyBhbmQgXCJjbGllbnRcIiBwcm9wZXJ0aWVzLCB0aG91Z2ggdGhhdCBpcyBub3QgYWx3YXlzIHRydWUgaW4gQ2hyb21lLlxyXG4gICAgICAgIHZhciB2ZXJ0U2Nyb2xsYmFyID0gTWF0aC5yb3VuZCh3aWR0aCArIGhvcml6UGFkKSAtIGNsaWVudFdpZHRoO1xyXG4gICAgICAgIHZhciBob3JpelNjcm9sbGJhciA9IE1hdGgucm91bmQoaGVpZ2h0ICsgdmVydFBhZCkgLSBjbGllbnRIZWlnaHQ7XHJcbiAgICAgICAgLy8gQ2hyb21lIGhhcyBhIHJhdGhlciB3ZWlyZCByb3VuZGluZyBvZiBcImNsaWVudFwiIHByb3BlcnRpZXMuXHJcbiAgICAgICAgLy8gRS5nLiBmb3IgYW4gZWxlbWVudCB3aXRoIGNvbnRlbnQgd2lkdGggb2YgMzE0LjJweCBpdCBzb21ldGltZXMgZ2l2ZXNcclxuICAgICAgICAvLyB0aGUgY2xpZW50IHdpZHRoIG9mIDMxNXB4IGFuZCBmb3IgdGhlIHdpZHRoIG9mIDMxNC43cHggaXQgbWF5IGdpdmVcclxuICAgICAgICAvLyAzMTRweC4gQW5kIGl0IGRvZXNuJ3QgaGFwcGVuIGFsbCB0aGUgdGltZS4gU28ganVzdCBpZ25vcmUgdGhpcyBkZWx0YVxyXG4gICAgICAgIC8vIGFzIGEgbm9uLXJlbGV2YW50LlxyXG4gICAgICAgIGlmIChNYXRoLmFicyh2ZXJ0U2Nyb2xsYmFyKSAhPT0gMSkge1xyXG4gICAgICAgICAgICB3aWR0aCAtPSB2ZXJ0U2Nyb2xsYmFyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoTWF0aC5hYnMoaG9yaXpTY3JvbGxiYXIpICE9PSAxKSB7XHJcbiAgICAgICAgICAgIGhlaWdodCAtPSBob3JpelNjcm9sbGJhcjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY3JlYXRlUmVjdEluaXQocGFkZGluZ3MubGVmdCwgcGFkZGluZ3MudG9wLCB3aWR0aCwgaGVpZ2h0KTtcclxufVxyXG4vKipcclxuICogQ2hlY2tzIHdoZXRoZXIgcHJvdmlkZWQgZWxlbWVudCBpcyBhbiBpbnN0YW5jZSBvZiB0aGUgU1ZHR3JhcGhpY3NFbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG52YXIgaXNTVkdHcmFwaGljc0VsZW1lbnQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgLy8gU29tZSBicm93c2VycywgbmFtZWx5IElFIGFuZCBFZGdlLCBkb24ndCBoYXZlIHRoZSBTVkdHcmFwaGljc0VsZW1lbnRcclxuICAgIC8vIGludGVyZmFjZS5cclxuICAgIGlmICh0eXBlb2YgU1ZHR3JhcGhpY3NFbGVtZW50ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0KSB7IHJldHVybiB0YXJnZXQgaW5zdGFuY2VvZiBnZXRXaW5kb3dPZih0YXJnZXQpLlNWR0dyYXBoaWNzRWxlbWVudDsgfTtcclxuICAgIH1cclxuICAgIC8vIElmIGl0J3Mgc28sIHRoZW4gY2hlY2sgdGhhdCBlbGVtZW50IGlzIGF0IGxlYXN0IGFuIGluc3RhbmNlIG9mIHRoZVxyXG4gICAgLy8gU1ZHRWxlbWVudCBhbmQgdGhhdCBpdCBoYXMgdGhlIFwiZ2V0QkJveFwiIG1ldGhvZC5cclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1leHRyYS1wYXJlbnNcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0KSB7IHJldHVybiAodGFyZ2V0IGluc3RhbmNlb2YgZ2V0V2luZG93T2YodGFyZ2V0KS5TVkdFbGVtZW50ICYmXHJcbiAgICAgICAgdHlwZW9mIHRhcmdldC5nZXRCQm94ID09PSAnZnVuY3Rpb24nKTsgfTtcclxufSkoKTtcclxuLyoqXHJcbiAqIENoZWNrcyB3aGV0aGVyIHByb3ZpZGVkIGVsZW1lbnQgaXMgYSBkb2N1bWVudCBlbGVtZW50ICg8aHRtbD4pLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdG8gYmUgY2hlY2tlZC5cclxuICogQHJldHVybnMge2Jvb2xlYW59XHJcbiAqL1xyXG5mdW5jdGlvbiBpc0RvY3VtZW50RWxlbWVudCh0YXJnZXQpIHtcclxuICAgIHJldHVybiB0YXJnZXQgPT09IGdldFdpbmRvd09mKHRhcmdldCkuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG59XHJcbi8qKlxyXG4gKiBDYWxjdWxhdGVzIGFuIGFwcHJvcHJpYXRlIGNvbnRlbnQgcmVjdGFuZ2xlIGZvciBwcm92aWRlZCBodG1sIG9yIHN2ZyBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgY29udGVudCByZWN0YW5nbGUgb2Ygd2hpY2ggbmVlZHMgdG8gYmUgY2FsY3VsYXRlZC5cclxuICogQHJldHVybnMge0RPTVJlY3RJbml0fVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0Q29udGVudFJlY3QodGFyZ2V0KSB7XHJcbiAgICBpZiAoIWlzQnJvd3Nlcikge1xyXG4gICAgICAgIHJldHVybiBlbXB0eVJlY3Q7XHJcbiAgICB9XHJcbiAgICBpZiAoaXNTVkdHcmFwaGljc0VsZW1lbnQodGFyZ2V0KSkge1xyXG4gICAgICAgIHJldHVybiBnZXRTVkdDb250ZW50UmVjdCh0YXJnZXQpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGdldEhUTUxFbGVtZW50Q29udGVudFJlY3QodGFyZ2V0KTtcclxufVxyXG4vKipcclxuICogQ3JlYXRlcyByZWN0YW5nbGUgd2l0aCBhbiBpbnRlcmZhY2Ugb2YgdGhlIERPTVJlY3RSZWFkT25seS5cclxuICogU3BlYzogaHR0cHM6Ly9kcmFmdHMuZnh0Zi5vcmcvZ2VvbWV0cnkvI2RvbXJlY3RyZWFkb25seVxyXG4gKlxyXG4gKiBAcGFyYW0ge0RPTVJlY3RJbml0fSByZWN0SW5pdCAtIE9iamVjdCB3aXRoIHJlY3RhbmdsZSdzIHgveSBjb29yZGluYXRlcyBhbmQgZGltZW5zaW9ucy5cclxuICogQHJldHVybnMge0RPTVJlY3RSZWFkT25seX1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZVJlYWRPbmx5UmVjdChfYSkge1xyXG4gICAgdmFyIHggPSBfYS54LCB5ID0gX2EueSwgd2lkdGggPSBfYS53aWR0aCwgaGVpZ2h0ID0gX2EuaGVpZ2h0O1xyXG4gICAgLy8gSWYgRE9NUmVjdFJlYWRPbmx5IGlzIGF2YWlsYWJsZSB1c2UgaXQgYXMgYSBwcm90b3R5cGUgZm9yIHRoZSByZWN0YW5nbGUuXHJcbiAgICB2YXIgQ29uc3RyID0gdHlwZW9mIERPTVJlY3RSZWFkT25seSAhPT0gJ3VuZGVmaW5lZCcgPyBET01SZWN0UmVhZE9ubHkgOiBPYmplY3Q7XHJcbiAgICB2YXIgcmVjdCA9IE9iamVjdC5jcmVhdGUoQ29uc3RyLnByb3RvdHlwZSk7XHJcbiAgICAvLyBSZWN0YW5nbGUncyBwcm9wZXJ0aWVzIGFyZSBub3Qgd3JpdGFibGUgYW5kIG5vbi1lbnVtZXJhYmxlLlxyXG4gICAgZGVmaW5lQ29uZmlndXJhYmxlKHJlY3QsIHtcclxuICAgICAgICB4OiB4LCB5OiB5LCB3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0LFxyXG4gICAgICAgIHRvcDogeSxcclxuICAgICAgICByaWdodDogeCArIHdpZHRoLFxyXG4gICAgICAgIGJvdHRvbTogaGVpZ2h0ICsgeSxcclxuICAgICAgICBsZWZ0OiB4XHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZWN0O1xyXG59XHJcbi8qKlxyXG4gKiBDcmVhdGVzIERPTVJlY3RJbml0IG9iamVjdCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgZGltZW5zaW9ucyBhbmQgdGhlIHgveSBjb29yZGluYXRlcy5cclxuICogU3BlYzogaHR0cHM6Ly9kcmFmdHMuZnh0Zi5vcmcvZ2VvbWV0cnkvI2RpY3RkZWYtZG9tcmVjdGluaXRcclxuICpcclxuICogQHBhcmFtIHtudW1iZXJ9IHggLSBYIGNvb3JkaW5hdGUuXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB5IC0gWSBjb29yZGluYXRlLlxyXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBSZWN0YW5nbGUncyB3aWR0aC5cclxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFJlY3RhbmdsZSdzIGhlaWdodC5cclxuICogQHJldHVybnMge0RPTVJlY3RJbml0fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlUmVjdEluaXQoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xyXG4gICAgcmV0dXJuIHsgeDogeCwgeTogeSwgd2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCB9O1xyXG59XG5cbi8qKlxyXG4gKiBDbGFzcyB0aGF0IGlzIHJlc3BvbnNpYmxlIGZvciBjb21wdXRhdGlvbnMgb2YgdGhlIGNvbnRlbnQgcmVjdGFuZ2xlIG9mXHJcbiAqIHByb3ZpZGVkIERPTSBlbGVtZW50IGFuZCBmb3Iga2VlcGluZyB0cmFjayBvZiBpdCdzIGNoYW5nZXMuXHJcbiAqL1xyXG52YXIgUmVzaXplT2JzZXJ2YXRpb24gPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUmVzaXplT2JzZXJ2YXRpb24uXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRvIGJlIG9ic2VydmVkLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZhdGlvbih0YXJnZXQpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBCcm9hZGNhc3RlZCB3aWR0aCBvZiBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5icm9hZGNhc3RXaWR0aCA9IDA7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQnJvYWRjYXN0ZWQgaGVpZ2h0IG9mIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmJyb2FkY2FzdEhlaWdodCA9IDA7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVmZXJlbmNlIHRvIHRoZSBsYXN0IG9ic2VydmVkIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGUge0RPTVJlY3RJbml0fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY29udGVudFJlY3RfID0gY3JlYXRlUmVjdEluaXQoMCwgMCwgMCwgMCk7XHJcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFVwZGF0ZXMgY29udGVudCByZWN0YW5nbGUgYW5kIHRlbGxzIHdoZXRoZXIgaXQncyB3aWR0aCBvciBoZWlnaHQgcHJvcGVydGllc1xyXG4gICAgICogaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGJyb2FkY2FzdC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2YXRpb24ucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciByZWN0ID0gZ2V0Q29udGVudFJlY3QodGhpcy50YXJnZXQpO1xyXG4gICAgICAgIHRoaXMuY29udGVudFJlY3RfID0gcmVjdDtcclxuICAgICAgICByZXR1cm4gKHJlY3Qud2lkdGggIT09IHRoaXMuYnJvYWRjYXN0V2lkdGggfHxcclxuICAgICAgICAgICAgcmVjdC5oZWlnaHQgIT09IHRoaXMuYnJvYWRjYXN0SGVpZ2h0KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFVwZGF0ZXMgJ2Jyb2FkY2FzdFdpZHRoJyBhbmQgJ2Jyb2FkY2FzdEhlaWdodCcgcHJvcGVydGllcyB3aXRoIGEgZGF0YVxyXG4gICAgICogZnJvbSB0aGUgY29ycmVzcG9uZGluZyBwcm9wZXJ0aWVzIG9mIHRoZSBsYXN0IG9ic2VydmVkIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtET01SZWN0SW5pdH0gTGFzdCBvYnNlcnZlZCBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2YXRpb24ucHJvdG90eXBlLmJyb2FkY2FzdFJlY3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHJlY3QgPSB0aGlzLmNvbnRlbnRSZWN0XztcclxuICAgICAgICB0aGlzLmJyb2FkY2FzdFdpZHRoID0gcmVjdC53aWR0aDtcclxuICAgICAgICB0aGlzLmJyb2FkY2FzdEhlaWdodCA9IHJlY3QuaGVpZ2h0O1xyXG4gICAgICAgIHJldHVybiByZWN0O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZhdGlvbjtcclxufSgpKTtcblxudmFyIFJlc2l6ZU9ic2VydmVyRW50cnkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgUmVzaXplT2JzZXJ2ZXJFbnRyeS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0VsZW1lbnR9IHRhcmdldCAtIEVsZW1lbnQgdGhhdCBpcyBiZWluZyBvYnNlcnZlZC5cclxuICAgICAqIEBwYXJhbSB7RE9NUmVjdEluaXR9IHJlY3RJbml0IC0gRGF0YSBvZiB0aGUgZWxlbWVudCdzIGNvbnRlbnQgcmVjdGFuZ2xlLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZlckVudHJ5KHRhcmdldCwgcmVjdEluaXQpIHtcclxuICAgICAgICB2YXIgY29udGVudFJlY3QgPSBjcmVhdGVSZWFkT25seVJlY3QocmVjdEluaXQpO1xyXG4gICAgICAgIC8vIEFjY29yZGluZyB0byB0aGUgc3BlY2lmaWNhdGlvbiBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgbm90IHdyaXRhYmxlXHJcbiAgICAgICAgLy8gYW5kIGFyZSBhbHNvIG5vdCBlbnVtZXJhYmxlIGluIHRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24uXHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBQcm9wZXJ0eSBhY2Nlc3NvcnMgYXJlIG5vdCBiZWluZyB1c2VkIGFzIHRoZXknZCByZXF1aXJlIHRvIGRlZmluZSBhXHJcbiAgICAgICAgLy8gcHJpdmF0ZSBXZWFrTWFwIHN0b3JhZ2Ugd2hpY2ggbWF5IGNhdXNlIG1lbW9yeSBsZWFrcyBpbiBicm93c2VycyB0aGF0XHJcbiAgICAgICAgLy8gZG9uJ3Qgc3VwcG9ydCB0aGlzIHR5cGUgb2YgY29sbGVjdGlvbnMuXHJcbiAgICAgICAgZGVmaW5lQ29uZmlndXJhYmxlKHRoaXMsIHsgdGFyZ2V0OiB0YXJnZXQsIGNvbnRlbnRSZWN0OiBjb250ZW50UmVjdCB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZlckVudHJ5O1xyXG59KCkpO1xuXG52YXIgUmVzaXplT2JzZXJ2ZXJTUEkgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgUmVzaXplT2JzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtSZXNpemVPYnNlcnZlckNhbGxiYWNrfSBjYWxsYmFjayAtIENhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgaW52b2tlZFxyXG4gICAgICogICAgICB3aGVuIG9uZSBvZiB0aGUgb2JzZXJ2ZWQgZWxlbWVudHMgY2hhbmdlcyBpdCdzIGNvbnRlbnQgZGltZW5zaW9ucy5cclxuICAgICAqIEBwYXJhbSB7UmVzaXplT2JzZXJ2ZXJDb250cm9sbGVyfSBjb250cm9sbGVyIC0gQ29udHJvbGxlciBpbnN0YW5jZSB3aGljaFxyXG4gICAgICogICAgICBpcyByZXNwb25zaWJsZSBmb3IgdGhlIHVwZGF0ZXMgb2Ygb2JzZXJ2ZXIuXHJcbiAgICAgKiBAcGFyYW0ge1Jlc2l6ZU9ic2VydmVyfSBjYWxsYmFja0N0eCAtIFJlZmVyZW5jZSB0byB0aGUgcHVibGljXHJcbiAgICAgKiAgICAgIFJlc2l6ZU9ic2VydmVyIGluc3RhbmNlIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRvIGNhbGxiYWNrIGZ1bmN0aW9uLlxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBSZXNpemVPYnNlcnZlclNQSShjYWxsYmFjaywgY29udHJvbGxlciwgY2FsbGJhY2tDdHgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb2xsZWN0aW9uIG9mIHJlc2l6ZSBvYnNlcnZhdGlvbnMgdGhhdCBoYXZlIGRldGVjdGVkIGNoYW5nZXMgaW4gZGltZW5zaW9uc1xyXG4gICAgICAgICAqIG9mIGVsZW1lbnRzLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGUge0FycmF5PFJlc2l6ZU9ic2VydmF0aW9uPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18gPSBbXTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZWdpc3RyeSBvZiB0aGUgUmVzaXplT2JzZXJ2YXRpb24gaW5zdGFuY2VzLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQHByaXZhdGUge01hcDxFbGVtZW50LCBSZXNpemVPYnNlcnZhdGlvbj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdGhpcy5vYnNlcnZhdGlvbnNfID0gbmV3IE1hcFNoaW0oKTtcclxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBjYWxsYmFjayBwcm92aWRlZCBhcyBwYXJhbWV0ZXIgMSBpcyBub3QgYSBmdW5jdGlvbi4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja18gPSBjYWxsYmFjaztcclxuICAgICAgICB0aGlzLmNvbnRyb2xsZXJfID0gY29udHJvbGxlcjtcclxuICAgICAgICB0aGlzLmNhbGxiYWNrQ3R4XyA9IGNhbGxiYWNrQ3R4O1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBTdGFydHMgb2JzZXJ2aW5nIHByb3ZpZGVkIGVsZW1lbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtFbGVtZW50fSB0YXJnZXQgLSBFbGVtZW50IHRvIGJlIG9ic2VydmVkLlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5vYnNlcnZlID0gZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCcxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IGhhdmUgdGhlIEVsZW1lbnQgaW50ZXJmYWNlLlxyXG4gICAgICAgIGlmICh0eXBlb2YgRWxlbWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgIShFbGVtZW50IGluc3RhbmNlb2YgT2JqZWN0KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIGdldFdpbmRvd09mKHRhcmdldCkuRWxlbWVudCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncGFyYW1ldGVyIDEgaXMgbm90IG9mIHR5cGUgXCJFbGVtZW50XCIuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBvYnNlcnZhdGlvbnMgPSB0aGlzLm9ic2VydmF0aW9uc187XHJcbiAgICAgICAgLy8gRG8gbm90aGluZyBpZiBlbGVtZW50IGlzIGFscmVhZHkgYmVpbmcgb2JzZXJ2ZWQuXHJcbiAgICAgICAgaWYgKG9ic2VydmF0aW9ucy5oYXModGFyZ2V0KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9ic2VydmF0aW9ucy5zZXQodGFyZ2V0LCBuZXcgUmVzaXplT2JzZXJ2YXRpb24odGFyZ2V0KSk7XHJcbiAgICAgICAgdGhpcy5jb250cm9sbGVyXy5hZGRPYnNlcnZlcih0aGlzKTtcclxuICAgICAgICAvLyBGb3JjZSB0aGUgdXBkYXRlIG9mIG9ic2VydmF0aW9ucy5cclxuICAgICAgICB0aGlzLmNvbnRyb2xsZXJfLnJlZnJlc2goKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFN0b3BzIG9ic2VydmluZyBwcm92aWRlZCBlbGVtZW50LlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RWxlbWVudH0gdGFyZ2V0IC0gRWxlbWVudCB0byBzdG9wIG9ic2VydmluZy5cclxuICAgICAqIEByZXR1cm5zIHt2b2lkfVxyXG4gICAgICovXHJcbiAgICBSZXNpemVPYnNlcnZlclNQSS5wcm90b3R5cGUudW5vYnNlcnZlID0gZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCcxIGFyZ3VtZW50IHJlcXVpcmVkLCBidXQgb25seSAwIHByZXNlbnQuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIERvIG5vdGhpbmcgaWYgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IGhhdmUgdGhlIEVsZW1lbnQgaW50ZXJmYWNlLlxyXG4gICAgICAgIGlmICh0eXBlb2YgRWxlbWVudCA9PT0gJ3VuZGVmaW5lZCcgfHwgIShFbGVtZW50IGluc3RhbmNlb2YgT2JqZWN0KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghKHRhcmdldCBpbnN0YW5jZW9mIGdldFdpbmRvd09mKHRhcmdldCkuRWxlbWVudCkpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncGFyYW1ldGVyIDEgaXMgbm90IG9mIHR5cGUgXCJFbGVtZW50XCIuJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBvYnNlcnZhdGlvbnMgPSB0aGlzLm9ic2VydmF0aW9uc187XHJcbiAgICAgICAgLy8gRG8gbm90aGluZyBpZiBlbGVtZW50IGlzIG5vdCBiZWluZyBvYnNlcnZlZC5cclxuICAgICAgICBpZiAoIW9ic2VydmF0aW9ucy5oYXModGFyZ2V0KSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9ic2VydmF0aW9ucy5kZWxldGUodGFyZ2V0KTtcclxuICAgICAgICBpZiAoIW9ic2VydmF0aW9ucy5zaXplKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlcl8ucmVtb3ZlT2JzZXJ2ZXIodGhpcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcHMgb2JzZXJ2aW5nIGFsbCBlbGVtZW50cy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5jbGVhckFjdGl2ZSgpO1xyXG4gICAgICAgIHRoaXMub2JzZXJ2YXRpb25zXy5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMuY29udHJvbGxlcl8ucmVtb3ZlT2JzZXJ2ZXIodGhpcyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb2xsZWN0cyBvYnNlcnZhdGlvbiBpbnN0YW5jZXMgdGhlIGFzc29jaWF0ZWQgZWxlbWVudCBvZiB3aGljaCBoYXMgY2hhbmdlZFxyXG4gICAgICogaXQncyBjb250ZW50IHJlY3RhbmdsZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLmdhdGhlckFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuY2xlYXJBY3RpdmUoKTtcclxuICAgICAgICB0aGlzLm9ic2VydmF0aW9uc18uZm9yRWFjaChmdW5jdGlvbiAob2JzZXJ2YXRpb24pIHtcclxuICAgICAgICAgICAgaWYgKG9ic2VydmF0aW9uLmlzQWN0aXZlKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18ucHVzaChvYnNlcnZhdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEludm9rZXMgaW5pdGlhbCBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIGEgbGlzdCBvZiBSZXNpemVPYnNlcnZlckVudHJ5XHJcbiAgICAgKiBpbnN0YW5jZXMgY29sbGVjdGVkIGZyb20gYWN0aXZlIHJlc2l6ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5icm9hZGNhc3RBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gRG8gbm90aGluZyBpZiBvYnNlcnZlciBkb2Vzbid0IGhhdmUgYWN0aXZlIG9ic2VydmF0aW9ucy5cclxuICAgICAgICBpZiAoIXRoaXMuaGFzQWN0aXZlKCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgY3R4ID0gdGhpcy5jYWxsYmFja0N0eF87XHJcbiAgICAgICAgLy8gQ3JlYXRlIFJlc2l6ZU9ic2VydmVyRW50cnkgaW5zdGFuY2UgZm9yIGV2ZXJ5IGFjdGl2ZSBvYnNlcnZhdGlvbi5cclxuICAgICAgICB2YXIgZW50cmllcyA9IHRoaXMuYWN0aXZlT2JzZXJ2YXRpb25zXy5tYXAoZnVuY3Rpb24gKG9ic2VydmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVzaXplT2JzZXJ2ZXJFbnRyeShvYnNlcnZhdGlvbi50YXJnZXQsIG9ic2VydmF0aW9uLmJyb2FkY2FzdFJlY3QoKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFja18uY2FsbChjdHgsIGVudHJpZXMsIGN0eCk7XHJcbiAgICAgICAgdGhpcy5jbGVhckFjdGl2ZSgpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXJzIHRoZSBjb2xsZWN0aW9uIG9mIGFjdGl2ZSBvYnNlcnZhdGlvbnMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3ZvaWR9XHJcbiAgICAgKi9cclxuICAgIFJlc2l6ZU9ic2VydmVyU1BJLnByb3RvdHlwZS5jbGVhckFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmFjdGl2ZU9ic2VydmF0aW9uc18uc3BsaWNlKDApO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVGVsbHMgd2hldGhlciBvYnNlcnZlciBoYXMgYWN0aXZlIG9ic2VydmF0aW9ucy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuICAgICAqL1xyXG4gICAgUmVzaXplT2JzZXJ2ZXJTUEkucHJvdG90eXBlLmhhc0FjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVPYnNlcnZhdGlvbnNfLmxlbmd0aCA+IDA7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFJlc2l6ZU9ic2VydmVyU1BJO1xyXG59KCkpO1xuXG4vLyBSZWdpc3RyeSBvZiBpbnRlcm5hbCBvYnNlcnZlcnMuIElmIFdlYWtNYXAgaXMgbm90IGF2YWlsYWJsZSB1c2UgY3VycmVudCBzaGltXHJcbi8vIGZvciB0aGUgTWFwIGNvbGxlY3Rpb24gYXMgaXQgaGFzIGFsbCByZXF1aXJlZCBtZXRob2RzIGFuZCBiZWNhdXNlIFdlYWtNYXBcclxuLy8gY2FuJ3QgYmUgZnVsbHkgcG9seWZpbGxlZCBhbnl3YXkuXHJcbnZhciBvYnNlcnZlcnMgPSB0eXBlb2YgV2Vha01hcCAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgV2Vha01hcCgpIDogbmV3IE1hcFNoaW0oKTtcclxuLyoqXHJcbiAqIFJlc2l6ZU9ic2VydmVyIEFQSS4gRW5jYXBzdWxhdGVzIHRoZSBSZXNpemVPYnNlcnZlciBTUEkgaW1wbGVtZW50YXRpb25cclxuICogZXhwb3Npbmcgb25seSB0aG9zZSBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzIHRoYXQgYXJlIGRlZmluZWQgaW4gdGhlIHNwZWMuXHJcbiAqL1xyXG52YXIgUmVzaXplT2JzZXJ2ZXIgPSAvKiogQGNsYXNzICovIChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgUmVzaXplT2JzZXJ2ZXIuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtSZXNpemVPYnNlcnZlckNhbGxiYWNrfSBjYWxsYmFjayAtIENhbGxiYWNrIHRoYXQgaXMgaW52b2tlZCB3aGVuXHJcbiAgICAgKiAgICAgIGRpbWVuc2lvbnMgb2YgdGhlIG9ic2VydmVkIGVsZW1lbnRzIGNoYW5nZS5cclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gUmVzaXplT2JzZXJ2ZXIoY2FsbGJhY2spIHtcclxuICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVzaXplT2JzZXJ2ZXIpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbi4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJzEgYXJndW1lbnQgcmVxdWlyZWQsIGJ1dCBvbmx5IDAgcHJlc2VudC4nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGNvbnRyb2xsZXIgPSBSZXNpemVPYnNlcnZlckNvbnRyb2xsZXIuZ2V0SW5zdGFuY2UoKTtcclxuICAgICAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXJTUEkoY2FsbGJhY2ssIGNvbnRyb2xsZXIsIHRoaXMpO1xyXG4gICAgICAgIG9ic2VydmVycy5zZXQodGhpcywgb2JzZXJ2ZXIpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFJlc2l6ZU9ic2VydmVyO1xyXG59KCkpO1xyXG4vLyBFeHBvc2UgcHVibGljIG1ldGhvZHMgb2YgUmVzaXplT2JzZXJ2ZXIuXHJcbltcclxuICAgICdvYnNlcnZlJyxcclxuICAgICd1bm9ic2VydmUnLFxyXG4gICAgJ2Rpc2Nvbm5lY3QnXHJcbl0uZm9yRWFjaChmdW5jdGlvbiAobWV0aG9kKSB7XHJcbiAgICBSZXNpemVPYnNlcnZlci5wcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX2E7XHJcbiAgICAgICAgcmV0dXJuIChfYSA9IG9ic2VydmVycy5nZXQodGhpcykpW21ldGhvZF0uYXBwbHkoX2EsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG59KTtcblxudmFyIGluZGV4ID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIC8vIEV4cG9ydCBleGlzdGluZyBpbXBsZW1lbnRhdGlvbiBpZiBhdmFpbGFibGUuXHJcbiAgICBpZiAodHlwZW9mIGdsb2JhbCQxLlJlc2l6ZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHJldHVybiBnbG9iYWwkMS5SZXNpemVPYnNlcnZlcjtcclxuICAgIH1cclxuICAgIHJldHVybiBSZXNpemVPYnNlcnZlcjtcclxufSkoKTtcblxuZXhwb3J0IGRlZmF1bHQgaW5kZXg7XG4iLCJpbXBvcnQgUmVzaXplT2JzZXJ2ZXIgZnJvbSAncmVzaXplLW9ic2VydmVyLXBvbHlmaWxsJztcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gQ29uc3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxudmFyIGVsZW1lbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBvblJlc2l6ZShlbnRpdGllcykge1xuICBlbnRpdGllcy5mb3JFYWNoKGZ1bmN0aW9uIChlbnRpdHkpIHtcbiAgICB2YXIgX2VsZW1lbnRMaXN0ZW5lcnMkZ2V0O1xuICAgIHZhciB0YXJnZXQgPSBlbnRpdHkudGFyZ2V0O1xuICAgIChfZWxlbWVudExpc3RlbmVycyRnZXQgPSBlbGVtZW50TGlzdGVuZXJzLmdldCh0YXJnZXQpKSA9PT0gbnVsbCB8fCBfZWxlbWVudExpc3RlbmVycyRnZXQgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9lbGVtZW50TGlzdGVuZXJzJGdldC5mb3JFYWNoKGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGxpc3RlbmVyKHRhcmdldCk7XG4gICAgfSk7XG4gIH0pO1xufVxuLy8gTm90ZTogUmVzaXplT2JzZXJ2ZXIgcG9seWZpbGwgbm90IHN1cHBvcnQgb3B0aW9uIHRvIG1lYXN1cmUgYm9yZGVyLWJveCByZXNpemVcbnZhciByZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcihvblJlc2l6ZSk7XG4vLyBEZXYgZW52IG9ubHlcbmV4cG9ydCB2YXIgX2VsID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/IGVsZW1lbnRMaXN0ZW5lcnMgOiBudWxsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5leHBvcnQgdmFyIF9ycyA9IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyBvblJlc2l6ZSA6IG51bGw7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBPYnNlcnZlID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmUoZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgaWYgKCFlbGVtZW50TGlzdGVuZXJzLmhhcyhlbGVtZW50KSkge1xuICAgIGVsZW1lbnRMaXN0ZW5lcnMuc2V0KGVsZW1lbnQsIG5ldyBTZXQoKSk7XG4gICAgcmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShlbGVtZW50KTtcbiAgfVxuICBlbGVtZW50TGlzdGVuZXJzLmdldChlbGVtZW50KS5hZGQoY2FsbGJhY2spO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHVub2JzZXJ2ZShlbGVtZW50LCBjYWxsYmFjaykge1xuICBpZiAoZWxlbWVudExpc3RlbmVycy5oYXMoZWxlbWVudCkpIHtcbiAgICBlbGVtZW50TGlzdGVuZXJzLmdldChlbGVtZW50KS5kZWxldGUoY2FsbGJhY2spO1xuICAgIGlmICghZWxlbWVudExpc3RlbmVycy5nZXQoZWxlbWVudCkuc2l6ZSkge1xuICAgICAgcmVzaXplT2JzZXJ2ZXIudW5vYnNlcnZlKGVsZW1lbnQpO1xuICAgICAgZWxlbWVudExpc3RlbmVycy5kZWxldGUoZWxlbWVudCk7XG4gICAgfVxuICB9XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn0iLCJpbXBvcnQgdG9Qcm9wZXJ0eUtleSBmcm9tIFwiLi90b1Byb3BlcnR5S2V5LmpzXCI7XG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldO1xuICAgIGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgaWYgKFwidmFsdWVcIiBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCB0b1Byb3BlcnR5S2V5KGRlc2NyaXB0b3Iua2V5KSwgZGVzY3JpcHRvcik7XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9jcmVhdGVDbGFzcyhDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHtcbiAgaWYgKHByb3RvUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7XG4gIGlmIChzdGF0aWNQcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KENvbnN0cnVjdG9yLCBcInByb3RvdHlwZVwiLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pO1xuICByZXR1cm4gQ29uc3RydWN0b3I7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX3NldFByb3RvdHlwZU9mKG8sIHApIHtcbiAgX3NldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mLmJpbmQoKSA6IGZ1bmN0aW9uIF9zZXRQcm90b3R5cGVPZihvLCBwKSB7XG4gICAgby5fX3Byb3RvX18gPSBwO1xuICAgIHJldHVybiBvO1xuICB9O1xuICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xufSIsImltcG9ydCBzZXRQcm90b3R5cGVPZiBmcm9tIFwiLi9zZXRQcm90b3R5cGVPZi5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gIGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7XG4gIH1cbiAgc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBzdWJDbGFzcyxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHN1YkNsYXNzLCBcInByb3RvdHlwZVwiLCB7XG4gICAgd3JpdGFibGU6IGZhbHNlXG4gIH0pO1xuICBpZiAoc3VwZXJDbGFzcykgc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpO1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gIF9nZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5nZXRQcm90b3R5cGVPZi5iaW5kKCkgOiBmdW5jdGlvbiBfZ2V0UHJvdG90eXBlT2Yobykge1xuICAgIHJldHVybiBvLl9fcHJvdG9fXyB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gIH07XG4gIHJldHVybiBfZ2V0UHJvdG90eXBlT2Yobyk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gX2lzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlO1xuICBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlO1xuICB0cnkge1xuICAgIEJvb2xlYW4ucHJvdG90eXBlLnZhbHVlT2YuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChCb29sZWFuLCBbXSwgZnVuY3Rpb24gKCkge30pKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQoc2VsZikge1xuICBpZiAoc2VsZiA9PT0gdm9pZCAwKSB7XG4gICAgdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO1xuICB9XG4gIHJldHVybiBzZWxmO1xufSIsImltcG9ydCBfdHlwZW9mIGZyb20gXCIuL3R5cGVvZi5qc1wiO1xuaW1wb3J0IGFzc2VydFRoaXNJbml0aWFsaXplZCBmcm9tIFwiLi9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHNlbGYsIGNhbGwpIHtcbiAgaWYgKGNhbGwgJiYgKF90eXBlb2YoY2FsbCkgPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGNhbGwgPT09IFwiZnVuY3Rpb25cIikpIHtcbiAgICByZXR1cm4gY2FsbDtcbiAgfSBlbHNlIGlmIChjYWxsICE9PSB2b2lkIDApIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRGVyaXZlZCBjb25zdHJ1Y3RvcnMgbWF5IG9ubHkgcmV0dXJuIG9iamVjdCBvciB1bmRlZmluZWRcIik7XG4gIH1cbiAgcmV0dXJuIGFzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn0iLCJpbXBvcnQgZ2V0UHJvdG90eXBlT2YgZnJvbSBcIi4vZ2V0UHJvdG90eXBlT2YuanNcIjtcbmltcG9ydCBpc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QgZnJvbSBcIi4vaXNOYXRpdmVSZWZsZWN0Q29uc3RydWN0LmpzXCI7XG5pbXBvcnQgcG9zc2libGVDb25zdHJ1Y3RvclJldHVybiBmcm9tIFwiLi9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBfY3JlYXRlU3VwZXIoRGVyaXZlZCkge1xuICB2YXIgaGFzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCA9IGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpO1xuICByZXR1cm4gZnVuY3Rpb24gX2NyZWF0ZVN1cGVySW50ZXJuYWwoKSB7XG4gICAgdmFyIFN1cGVyID0gZ2V0UHJvdG90eXBlT2YoRGVyaXZlZCksXG4gICAgICByZXN1bHQ7XG4gICAgaWYgKGhhc05hdGl2ZVJlZmxlY3RDb25zdHJ1Y3QpIHtcbiAgICAgIHZhciBOZXdUYXJnZXQgPSBnZXRQcm90b3R5cGVPZih0aGlzKS5jb25zdHJ1Y3RvcjtcbiAgICAgIHJlc3VsdCA9IFJlZmxlY3QuY29uc3RydWN0KFN1cGVyLCBhcmd1bWVudHMsIE5ld1RhcmdldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IFN1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICAgIHJldHVybiBwb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuKHRoaXMsIHJlc3VsdCk7XG4gIH07XG59IiwiaW1wb3J0IF9jbGFzc0NhbGxDaGVjayBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY2xhc3NDYWxsQ2hlY2tcIjtcbmltcG9ydCBfY3JlYXRlQ2xhc3MgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZUNsYXNzXCI7XG5pbXBvcnQgX2luaGVyaXRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9pbmhlcml0c1wiO1xuaW1wb3J0IF9jcmVhdGVTdXBlciBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vY3JlYXRlU3VwZXJcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0Jztcbi8qKlxuICogRmFsbGJhY2sgdG8gZmluZERPTU5vZGUgaWYgb3JpZ2luIHJlZiBkbyBub3QgcHJvdmlkZSBhbnkgZG9tIGVsZW1lbnRcbiAqL1xudmFyIERvbVdyYXBwZXIgPSAvKiNfX1BVUkVfXyovZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgX2luaGVyaXRzKERvbVdyYXBwZXIsIF9SZWFjdCRDb21wb25lbnQpO1xuICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKERvbVdyYXBwZXIpO1xuICBmdW5jdGlvbiBEb21XcmFwcGVyKCkge1xuICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBEb21XcmFwcGVyKTtcbiAgICByZXR1cm4gX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cbiAgX2NyZWF0ZUNsYXNzKERvbVdyYXBwZXIsIFt7XG4gICAga2V5OiBcInJlbmRlclwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5jaGlsZHJlbjtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIERvbVdyYXBwZXI7XG59KFJlYWN0LkNvbXBvbmVudCk7XG5leHBvcnQgeyBEb21XcmFwcGVyIGFzIGRlZmF1bHQgfTsiLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgdmFyIENvbGxlY3Rpb25Db250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG4vKipcbiAqIENvbGxlY3QgYWxsIHRoZSByZXNpemUgZXZlbnQgZnJvbSBjaGlsZHJlbiBSZXNpemVPYnNlcnZlclxuICovXG5leHBvcnQgZnVuY3Rpb24gQ29sbGVjdGlvbihfcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IF9yZWYuY2hpbGRyZW4sXG4gICAgb25CYXRjaFJlc2l6ZSA9IF9yZWYub25CYXRjaFJlc2l6ZTtcbiAgdmFyIHJlc2l6ZUlkUmVmID0gUmVhY3QudXNlUmVmKDApO1xuICB2YXIgcmVzaXplSW5mb3NSZWYgPSBSZWFjdC51c2VSZWYoW10pO1xuICB2YXIgb25Db2xsZWN0aW9uUmVzaXplID0gUmVhY3QudXNlQ29udGV4dChDb2xsZWN0aW9uQ29udGV4dCk7XG4gIHZhciBvblJlc2l6ZSA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uIChzaXplLCBlbGVtZW50LCBkYXRhKSB7XG4gICAgcmVzaXplSWRSZWYuY3VycmVudCArPSAxO1xuICAgIHZhciBjdXJyZW50SWQgPSByZXNpemVJZFJlZi5jdXJyZW50O1xuICAgIHJlc2l6ZUluZm9zUmVmLmN1cnJlbnQucHVzaCh7XG4gICAgICBzaXplOiBzaXplLFxuICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgIGRhdGE6IGRhdGFcbiAgICB9KTtcbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChjdXJyZW50SWQgPT09IHJlc2l6ZUlkUmVmLmN1cnJlbnQpIHtcbiAgICAgICAgb25CYXRjaFJlc2l6ZSA9PT0gbnVsbCB8fCBvbkJhdGNoUmVzaXplID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkJhdGNoUmVzaXplKHJlc2l6ZUluZm9zUmVmLmN1cnJlbnQpO1xuICAgICAgICByZXNpemVJbmZvc1JlZi5jdXJyZW50ID0gW107XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gQ29udGludWUgYnViYmxpbmcgaWYgcGFyZW50IGV4aXN0XG4gICAgb25Db2xsZWN0aW9uUmVzaXplID09PSBudWxsIHx8IG9uQ29sbGVjdGlvblJlc2l6ZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25Db2xsZWN0aW9uUmVzaXplKHNpemUsIGVsZW1lbnQsIGRhdGEpO1xuICB9LCBbb25CYXRjaFJlc2l6ZSwgb25Db2xsZWN0aW9uUmVzaXplXSk7XG4gIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChDb2xsZWN0aW9uQ29udGV4dC5Qcm92aWRlciwge1xuICAgIHZhbHVlOiBvblJlc2l6ZVxuICB9LCBjaGlsZHJlbik7XG59IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCB7IGNvbXBvc2VSZWYsIHN1cHBvcnRSZWYgfSBmcm9tIFwicmMtdXRpbC9lcy9yZWZcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBmaW5kRE9NTm9kZSBmcm9tIFwicmMtdXRpbC9lcy9Eb20vZmluZERPTU5vZGVcIjtcbmltcG9ydCB7IG9ic2VydmUsIHVub2JzZXJ2ZSB9IGZyb20gJy4uL3V0aWxzL29ic2VydmVyVXRpbCc7XG5pbXBvcnQgRG9tV3JhcHBlciBmcm9tICcuL0RvbVdyYXBwZXInO1xuaW1wb3J0IHsgQ29sbGVjdGlvbkNvbnRleHQgfSBmcm9tICcuLi9Db2xsZWN0aW9uJztcbmZ1bmN0aW9uIFNpbmdsZU9ic2VydmVyKHByb3BzLCByZWYpIHtcbiAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgZGlzYWJsZWQgPSBwcm9wcy5kaXNhYmxlZDtcbiAgdmFyIGVsZW1lbnRSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIHZhciB3cmFwcGVyUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICB2YXIgb25Db2xsZWN0aW9uUmVzaXplID0gUmVhY3QudXNlQ29udGV4dChDb2xsZWN0aW9uQ29udGV4dCk7XG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBDaGlsZHJlbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgdmFyIGlzUmVuZGVyUHJvcHMgPSB0eXBlb2YgY2hpbGRyZW4gPT09ICdmdW5jdGlvbic7XG4gIHZhciBtZXJnZWRDaGlsZHJlbiA9IGlzUmVuZGVyUHJvcHMgPyBjaGlsZHJlbihlbGVtZW50UmVmKSA6IGNoaWxkcmVuO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTaXplID09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBzaXplUmVmID0gUmVhY3QudXNlUmVmKHtcbiAgICB3aWR0aDogLTEsXG4gICAgaGVpZ2h0OiAtMSxcbiAgICBvZmZzZXRXaWR0aDogLTEsXG4gICAgb2Zmc2V0SGVpZ2h0OiAtMVxuICB9KTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVmID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgY2FuUmVmID0gIWlzUmVuZGVyUHJvcHMgJiYgLyojX19QVVJFX18qL1JlYWN0LmlzVmFsaWRFbGVtZW50KG1lcmdlZENoaWxkcmVuKSAmJiBzdXBwb3J0UmVmKG1lcmdlZENoaWxkcmVuKTtcbiAgdmFyIG9yaWdpblJlZiA9IGNhblJlZiA/IG1lcmdlZENoaWxkcmVuLnJlZiA6IG51bGw7XG4gIHZhciBtZXJnZWRSZWYgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gY29tcG9zZVJlZihvcmlnaW5SZWYsIGVsZW1lbnRSZWYpO1xuICB9LCBbb3JpZ2luUmVmLCBlbGVtZW50UmVmXSk7XG4gIHZhciBnZXREb20gPSBmdW5jdGlvbiBnZXREb20oKSB7XG4gICAgcmV0dXJuIGZpbmRET01Ob2RlKGVsZW1lbnRSZWYuY3VycmVudCkgfHwgZmluZERPTU5vZGUod3JhcHBlclJlZi5jdXJyZW50KTtcbiAgfTtcbiAgUmVhY3QudXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZ2V0RG9tKCk7XG4gIH0pO1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gT2JzZXJ2ZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBwcm9wc1JlZiA9IFJlYWN0LnVzZVJlZihwcm9wcyk7XG4gIHByb3BzUmVmLmN1cnJlbnQgPSBwcm9wcztcbiAgLy8gSGFuZGxlclxuICB2YXIgb25JbnRlcm5hbFJlc2l6ZSA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICB2YXIgX3Byb3BzUmVmJGN1cnJlbnQgPSBwcm9wc1JlZi5jdXJyZW50LFxuICAgICAgb25SZXNpemUgPSBfcHJvcHNSZWYkY3VycmVudC5vblJlc2l6ZSxcbiAgICAgIGRhdGEgPSBfcHJvcHNSZWYkY3VycmVudC5kYXRhO1xuICAgIHZhciBfdGFyZ2V0JGdldEJvdW5kaW5nQ2wgPSB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICB3aWR0aCA9IF90YXJnZXQkZ2V0Qm91bmRpbmdDbC53aWR0aCxcbiAgICAgIGhlaWdodCA9IF90YXJnZXQkZ2V0Qm91bmRpbmdDbC5oZWlnaHQ7XG4gICAgdmFyIG9mZnNldFdpZHRoID0gdGFyZ2V0Lm9mZnNldFdpZHRoLFxuICAgICAgb2Zmc2V0SGVpZ2h0ID0gdGFyZ2V0Lm9mZnNldEhlaWdodDtcbiAgICAvKipcbiAgICAgKiBSZXNpemUgb2JzZXJ2ZXIgdHJpZ2dlciB3aGVuIGNvbnRlbnQgc2l6ZSBjaGFuZ2VkLlxuICAgICAqIEluIG1vc3QgY2FzZSB3ZSBqdXN0IGNhcmUgYWJvdXQgZWxlbWVudCBzaXplLFxuICAgICAqIGxldCdzIHVzZSBgYm91bmRhcnlgIGluc3RlYWQgb2YgYGNvbnRlbnRSZWN0YCBoZXJlIHRvIGF2b2lkIHNoYWtpbmcuXG4gICAgICovXG4gICAgdmFyIGZpeGVkV2lkdGggPSBNYXRoLmZsb29yKHdpZHRoKTtcbiAgICB2YXIgZml4ZWRIZWlnaHQgPSBNYXRoLmZsb29yKGhlaWdodCk7XG4gICAgaWYgKHNpemVSZWYuY3VycmVudC53aWR0aCAhPT0gZml4ZWRXaWR0aCB8fCBzaXplUmVmLmN1cnJlbnQuaGVpZ2h0ICE9PSBmaXhlZEhlaWdodCB8fCBzaXplUmVmLmN1cnJlbnQub2Zmc2V0V2lkdGggIT09IG9mZnNldFdpZHRoIHx8IHNpemVSZWYuY3VycmVudC5vZmZzZXRIZWlnaHQgIT09IG9mZnNldEhlaWdodCkge1xuICAgICAgdmFyIHNpemUgPSB7XG4gICAgICAgIHdpZHRoOiBmaXhlZFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IGZpeGVkSGVpZ2h0LFxuICAgICAgICBvZmZzZXRXaWR0aDogb2Zmc2V0V2lkdGgsXG4gICAgICAgIG9mZnNldEhlaWdodDogb2Zmc2V0SGVpZ2h0XG4gICAgICB9O1xuICAgICAgc2l6ZVJlZi5jdXJyZW50ID0gc2l6ZTtcbiAgICAgIC8vIElFIGlzIHN0cmFuZ2UsIHJpZ2h0P1xuICAgICAgdmFyIG1lcmdlZE9mZnNldFdpZHRoID0gb2Zmc2V0V2lkdGggPT09IE1hdGgucm91bmQod2lkdGgpID8gd2lkdGggOiBvZmZzZXRXaWR0aDtcbiAgICAgIHZhciBtZXJnZWRPZmZzZXRIZWlnaHQgPSBvZmZzZXRIZWlnaHQgPT09IE1hdGgucm91bmQoaGVpZ2h0KSA/IGhlaWdodCA6IG9mZnNldEhlaWdodDtcbiAgICAgIHZhciBzaXplSW5mbyA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgc2l6ZSksIHt9LCB7XG4gICAgICAgIG9mZnNldFdpZHRoOiBtZXJnZWRPZmZzZXRXaWR0aCxcbiAgICAgICAgb2Zmc2V0SGVpZ2h0OiBtZXJnZWRPZmZzZXRIZWlnaHRcbiAgICAgIH0pO1xuICAgICAgLy8gTGV0IGNvbGxlY3Rpb24ga25vdyB3aGF0IGhhcHBlbmVkXG4gICAgICBvbkNvbGxlY3Rpb25SZXNpemUgPT09IG51bGwgfHwgb25Db2xsZWN0aW9uUmVzaXplID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkNvbGxlY3Rpb25SZXNpemUoc2l6ZUluZm8sIHRhcmdldCwgZGF0YSk7XG4gICAgICBpZiAob25SZXNpemUpIHtcbiAgICAgICAgLy8gZGVmZXIgdGhlIGNhbGxiYWNrIGJ1dCBub3QgZGVmZXIgdG8gbmV4dCBmcmFtZVxuICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBvblJlc2l6ZShzaXplSW5mbywgdGFyZ2V0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9LCBbXSk7XG4gIC8vIER5bmFtaWMgb2JzZXJ2ZVxuICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjdXJyZW50RWxlbWVudCA9IGdldERvbSgpO1xuICAgIGlmIChjdXJyZW50RWxlbWVudCAmJiAhZGlzYWJsZWQpIHtcbiAgICAgIG9ic2VydmUoY3VycmVudEVsZW1lbnQsIG9uSW50ZXJuYWxSZXNpemUpO1xuICAgIH1cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHVub2JzZXJ2ZShjdXJyZW50RWxlbWVudCwgb25JbnRlcm5hbFJlc2l6ZSk7XG4gICAgfTtcbiAgfSwgW2VsZW1lbnRSZWYuY3VycmVudCwgZGlzYWJsZWRdKTtcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoRG9tV3JhcHBlciwge1xuICAgIHJlZjogd3JhcHBlclJlZlxuICB9LCBjYW5SZWYgPyAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KG1lcmdlZENoaWxkcmVuLCB7XG4gICAgcmVmOiBtZXJnZWRSZWZcbiAgfSkgOiBtZXJnZWRDaGlsZHJlbik7XG59XG52YXIgUmVmU2luZ2xlT2JzZXJ2ZXIgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihTaW5nbGVPYnNlcnZlcik7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBSZWZTaW5nbGVPYnNlcnZlci5kaXNwbGF5TmFtZSA9ICdTaW5nbGVPYnNlcnZlcic7XG59XG5leHBvcnQgZGVmYXVsdCBSZWZTaW5nbGVPYnNlcnZlcjsiLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB0b0FycmF5IGZyb20gXCJyYy11dGlsL2VzL0NoaWxkcmVuL3RvQXJyYXlcIjtcbmltcG9ydCB7IHdhcm5pbmcgfSBmcm9tIFwicmMtdXRpbC9lcy93YXJuaW5nXCI7XG5pbXBvcnQgU2luZ2xlT2JzZXJ2ZXIgZnJvbSAnLi9TaW5nbGVPYnNlcnZlcic7XG5pbXBvcnQgeyBDb2xsZWN0aW9uIH0gZnJvbSAnLi9Db2xsZWN0aW9uJztcbnZhciBJTlRFUk5BTF9QUkVGSVhfS0VZID0gJ3JjLW9ic2VydmVyLWtleSc7XG5pbXBvcnQgeyBfcnMgfSBmcm9tICcuL3V0aWxzL29ic2VydmVyVXRpbCc7XG5leHBvcnQgeyAvKiogQHByaXZhdGUgVGVzdCBvbmx5IGZvciBtb2NrIHRyaWdnZXIgcmVzaXplIGV2ZW50ICovXG5fcnMgfTtcbmZ1bmN0aW9uIFJlc2l6ZU9ic2VydmVyKHByb3BzLCByZWYpIHtcbiAgdmFyIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW47XG4gIHZhciBjaGlsZE5vZGVzID0gdHlwZW9mIGNoaWxkcmVuID09PSAnZnVuY3Rpb24nID8gW2NoaWxkcmVuXSA6IHRvQXJyYXkoY2hpbGRyZW4pO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIGlmIChjaGlsZE5vZGVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHdhcm5pbmcoZmFsc2UsICdGaW5kIG1vcmUgdGhhbiBvbmUgY2hpbGQgbm9kZSB3aXRoIGBjaGlsZHJlbmAgaW4gUmVzaXplT2JzZXJ2ZXIuIFBsZWFzZSB1c2UgUmVzaXplT2JzZXJ2ZXIuQ29sbGVjdGlvbiBpbnN0ZWFkLicpO1xuICAgIH0gZWxzZSBpZiAoY2hpbGROb2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHdhcm5pbmcoZmFsc2UsICdgY2hpbGRyZW5gIG9mIFJlc2l6ZU9ic2VydmVyIGlzIGVtcHR5LiBOb3RoaW5nIGlzIGluIG9ic2VydmUuJyk7XG4gICAgfVxuICB9XG4gIHJldHVybiBjaGlsZE5vZGVzLm1hcChmdW5jdGlvbiAoY2hpbGQsIGluZGV4KSB7XG4gICAgdmFyIGtleSA9IChjaGlsZCA9PT0gbnVsbCB8fCBjaGlsZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogY2hpbGQua2V5KSB8fCBcIlwiLmNvbmNhdChJTlRFUk5BTF9QUkVGSVhfS0VZLCBcIi1cIikuY29uY2F0KGluZGV4KTtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoU2luZ2xlT2JzZXJ2ZXIsIF9leHRlbmRzKHt9LCBwcm9wcywge1xuICAgICAga2V5OiBrZXksXG4gICAgICByZWY6IGluZGV4ID09PSAwID8gcmVmIDogdW5kZWZpbmVkXG4gICAgfSksIGNoaWxkKTtcbiAgfSk7XG59XG52YXIgUmVmUmVzaXplT2JzZXJ2ZXIgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihSZXNpemVPYnNlcnZlcik7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBSZWZSZXNpemVPYnNlcnZlci5kaXNwbGF5TmFtZSA9ICdSZXNpemVPYnNlcnZlcic7XG59XG5SZWZSZXNpemVPYnNlcnZlci5Db2xsZWN0aW9uID0gQ29sbGVjdGlvbjtcbmV4cG9ydCBkZWZhdWx0IFJlZlJlc2l6ZU9ic2VydmVyOyIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmZ1bmN0aW9uIGdldFVzZUlkKCkge1xuICAvLyBXZSBuZWVkIGZ1bGx5IGNsb25lIFJlYWN0IGZ1bmN0aW9uIGhlcmUgdG8gYXZvaWQgd2VicGFjayB3YXJuaW5nIFJlYWN0IDE3IGRvIG5vdCBleHBvcnQgYHVzZUlkYFxuICB2YXIgZnVsbENsb25lID0gX29iamVjdFNwcmVhZCh7fSwgUmVhY3QpO1xuICByZXR1cm4gZnVsbENsb25lLnVzZUlkO1xufVxudmFyIHV1aWQgPSAwO1xuXG4vKiogQHByaXZhdGUgTm90ZSBvbmx5IHdvcmtlZCBpbiBkZXZlbG9wIGVudi4gTm90IHdvcmsgaW4gcHJvZHVjdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldFV1aWQoKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgdXVpZCA9IDA7XG4gIH1cbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZUlkKGlkKSB7XG4gIC8vIElubmVyIGlkIGZvciBhY2Nlc3NpYmlsaXR5IHVzYWdlLiBPbmx5IHdvcmsgaW4gY2xpZW50IHNpZGVcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKCdzc3ItaWQnKSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICBpbm5lcklkID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRJbm5lcklkID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcbiAgdmFyIHVzZU9yaWdpbklkID0gZ2V0VXNlSWQoKTtcbiAgdmFyIHJlYWN0TmF0aXZlSWQgPSB1c2VPcmlnaW5JZCA9PT0gbnVsbCB8fCB1c2VPcmlnaW5JZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogdXNlT3JpZ2luSWQoKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXVzZU9yaWdpbklkKSB7XG4gICAgICB2YXIgbmV4dElkID0gdXVpZDtcbiAgICAgIHV1aWQgKz0gMTtcbiAgICAgIHNldElubmVySWQoXCJyY191bmlxdWVfXCIuY29uY2F0KG5leHRJZCkpO1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIC8vIERldmVsb3BlciBwYXNzZWQgaWQgaXMgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aFxuICBpZiAoaWQpIHtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvLyBUZXN0IGVudiBhbHdheXMgcmV0dXJuIG1vY2sgaWRcbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAndGVzdCcpIHtcbiAgICByZXR1cm4gJ3Rlc3QtaWQnO1xuICB9XG5cbiAgLy8gUmV0dXJuIHJlYWN0IG5hdGl2ZSBpZCBvciBpbm5lciBpZFxuICByZXR1cm4gcmVhY3ROYXRpdmVJZCB8fCBpbm5lcklkO1xufSIsImV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgbmF2aWdhdG9yID09PSAndW5kZWZpbmVkJyB8fCB0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgYWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50IHx8IG5hdmlnYXRvci52ZW5kb3IgfHwgd2luZG93Lm9wZXJhO1xuICByZXR1cm4gLyhhbmRyb2lkfGJiXFxkK3xtZWVnbykuK21vYmlsZXxhdmFudGdvfGJhZGFcXC98YmxhY2tiZXJyeXxibGF6ZXJ8Y29tcGFsfGVsYWluZXxmZW5uZWN8aGlwdG9wfGllbW9iaWxlfGlwKGhvbmV8b2QpfGlyaXN8a2luZGxlfGxnZSB8bWFlbW98bWlkcHxtbXB8bW9iaWxlLitmaXJlZm94fG5ldGZyb250fG9wZXJhIG0ob2J8aW4paXxwYWxtKCBvcyk/fHBob25lfHAoaXhpfHJlKVxcL3xwbHVja2VyfHBvY2tldHxwc3B8c2VyaWVzKDR8NikwfHN5bWJpYW58dHJlb3x1cFxcLihicm93c2VyfGxpbmspfHZvZGFmb25lfHdhcHx3aW5kb3dzIGNlfHhkYXx4aWlub3xhbmRyb2lkfGlwYWR8cGxheWJvb2t8c2lsay9pLnRlc3QoYWdlbnQpIHx8IC8xMjA3fDYzMTB8NjU5MHwzZ3NvfDR0aHB8NTBbMS02XWl8Nzcwc3w4MDJzfGEgd2F8YWJhY3xhYyhlcnxvb3xzLSl8YWkoa298cm4pfGFsKGF2fGNhfGNvKXxhbW9pfGFuKGV4fG55fHl3KXxhcHR1fGFyKGNofGdvKXxhcyh0ZXx1cyl8YXR0d3xhdShkaXwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3LShufHUpfGM1NVxcL3xjYXBpfGNjd2F8Y2RtLXxjZWxsfGNodG18Y2xkY3xjbWQtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjLXN8ZGV2aXxkaWNhfGRtb2J8ZG8oY3xwKW98ZHMoMTJ8LWQpfGVsKDQ5fGFpKXxlbShsMnx1bCl8ZXIoaWN8azApfGVzbDh8ZXooWzQtN10wfG9zfHdhfHplKXxmZXRjfGZseSgtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmLTV8Zy1tb3xnbyhcXC53fG9kKXxncihhZHx1bil8aGFpZXxoY2l0fGhkLShtfHB8dCl8aGVpLXxoaShwdHx0YSl8aHAoIGl8aXApfGhzLWN8aHQoYygtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aS0oMjB8Z298bWEpfGkyMzB8aWFjKCB8LXxcXC8pfGlicm98aWRlYXxpZzAxfGlrb218aW0xa3xpbm5vfGlwYXF8aXJpc3xqYSh0fHYpYXxqYnJvfGplbXV8amlnc3xrZGRpfGtlaml8a2d0KCB8XFwvKXxrbG9ufGtwdCB8a3djLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHwtW2Etd10pfGxpYnd8bHlueHxtMS13fG0zZ2F8bTUwXFwvfG1hKHRlfHVpfHhvKXxtYygwMXwyMXxjYSl8bS1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dCgtfCB8b3x2KXx6eil8bXQoNTB8cDF8diApfG13YnB8bXl3YXxuMTBbMC0yXXxuMjBbMi0zXXxuMzAoMHwyKXxuNTAoMHwyfDUpfG43KDAoMHwxKXwxMCl8bmUoKGN8bSktfG9ufHRmfHdmfHdnfHd0KXxub2soNnxpKXxuenBofG8yaW18b3AodGl8d3YpfG9yYW58b3dnMXxwODAwfHBhbihhfGR8dCl8cGR4Z3xwZygxM3wtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuLTJ8cG8oY2t8cnR8c2UpfHByb3h8cHNpb3xwdC1nfHFhLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8LVsyLTddfGktKXxxdGVrfHIzODB8cjYwMHxyYWtzfHJpbTl8cm8odmV8em8pfHM1NVxcL3xzYShnZXxtYXxtbXxtc3xueXx2YSl8c2MoMDF8aC18b298cC0pfHNka1xcL3xzZShjKC18MHwxKXw0N3xtY3xuZHxyaSl8c2doLXxzaGFyfHNpZSgtfG0pfHNrLTB8c2woNDV8aWQpfHNtKGFsfGFyfGIzfGl0fHQ1KXxzbyhmdHxueSl8c3AoMDF8aC18di18diApfHN5KDAxfG1iKXx0MigxOHw1MCl8dDYoMDB8MTB8MTgpfHRhKGd0fGxrKXx0Y2wtfHRkZy18dGVsKGl8bSl8dGltLXx0LW1vfHRvKHBsfHNoKXx0cyg3MHxtLXxtM3xtNSl8dHgtOXx1cChcXC5ifGcxfHNpKXx1dHN0fHY0MDB8djc1MHx2ZXJpfHZpKHJnfHRlKXx2ayg0MHw1WzAtM118LXYpfHZtNDB8dm9kYXx2dWxjfHZ4KDUyfDUzfDYwfDYxfDcwfDgwfDgxfDgzfDg1fDk4KXx3M2MoLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhcy18eW91cnx6ZXRvfHp0ZS0vaS50ZXN0KGFnZW50ID09PSBudWxsIHx8IGFnZW50ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhZ2VudC5zdWJzdHIoMCwgNCkpO1xufSk7IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xudmFyIFRyaWdnZXJDb250ZXh0ID0gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUNvbnRleHQobnVsbCk7XG5leHBvcnQgZGVmYXVsdCBUcmlnZ2VyQ29udGV4dDsiLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5mdW5jdGlvbiB0b0FycmF5KHZhbCkge1xuICByZXR1cm4gdmFsID8gQXJyYXkuaXNBcnJheSh2YWwpID8gdmFsIDogW3ZhbF0gOiBbXTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZUFjdGlvbihtb2JpbGUsIGFjdGlvbiwgc2hvd0FjdGlvbiwgaGlkZUFjdGlvbikge1xuICByZXR1cm4gUmVhY3QudXNlTWVtbyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1lcmdlZFNob3dBY3Rpb24gPSB0b0FycmF5KHNob3dBY3Rpb24gIT09IG51bGwgJiYgc2hvd0FjdGlvbiAhPT0gdm9pZCAwID8gc2hvd0FjdGlvbiA6IGFjdGlvbik7XG4gICAgdmFyIG1lcmdlZEhpZGVBY3Rpb24gPSB0b0FycmF5KGhpZGVBY3Rpb24gIT09IG51bGwgJiYgaGlkZUFjdGlvbiAhPT0gdm9pZCAwID8gaGlkZUFjdGlvbiA6IGFjdGlvbik7XG4gICAgdmFyIHNob3dBY3Rpb25TZXQgPSBuZXcgU2V0KG1lcmdlZFNob3dBY3Rpb24pO1xuICAgIHZhciBoaWRlQWN0aW9uU2V0ID0gbmV3IFNldChtZXJnZWRIaWRlQWN0aW9uKTtcbiAgICBpZiAobW9iaWxlKSB7XG4gICAgICBpZiAoc2hvd0FjdGlvblNldC5oYXMoJ2hvdmVyJykpIHtcbiAgICAgICAgc2hvd0FjdGlvblNldC5kZWxldGUoJ2hvdmVyJyk7XG4gICAgICAgIHNob3dBY3Rpb25TZXQuYWRkKCdjbGljaycpO1xuICAgICAgfVxuICAgICAgaWYgKGhpZGVBY3Rpb25TZXQuaGFzKCdob3ZlcicpKSB7XG4gICAgICAgIGhpZGVBY3Rpb25TZXQuZGVsZXRlKCdob3ZlcicpO1xuICAgICAgICBoaWRlQWN0aW9uU2V0LmFkZCgnY2xpY2snKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtzaG93QWN0aW9uU2V0LCBoaWRlQWN0aW9uU2V0XTtcbiAgfSwgW21vYmlsZSwgYWN0aW9uLCBzaG93QWN0aW9uLCBoaWRlQWN0aW9uXSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gIGlmICghZWxlbWVudCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC5vZmZzZXRQYXJlbnQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoZWxlbWVudC5nZXRCQm94KSB7XG4gICAgICB2YXIgX2dldEJCb3ggPSBlbGVtZW50LmdldEJCb3goKSxcbiAgICAgICAgd2lkdGggPSBfZ2V0QkJveC53aWR0aCxcbiAgICAgICAgaGVpZ2h0ID0gX2dldEJCb3guaGVpZ2h0O1xuICAgICAgaWYgKHdpZHRoIHx8IGhlaWdodCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KSB7XG4gICAgICB2YXIgX2VsZW1lbnQkZ2V0Qm91bmRpbmdDID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgX3dpZHRoID0gX2VsZW1lbnQkZ2V0Qm91bmRpbmdDLndpZHRoLFxuICAgICAgICBfaGVpZ2h0ID0gX2VsZW1lbnQkZ2V0Qm91bmRpbmdDLmhlaWdodDtcbiAgICAgIGlmIChfd2lkdGggfHwgX2hlaWdodCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufSk7IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmZ1bmN0aW9uIGlzUG9pbnRzRXEoKSB7XG4gIHZhciBhMSA9IGFyZ3VtZW50cy5sZW5ndGggPiAwICYmIGFyZ3VtZW50c1swXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzBdIDogW107XG4gIHZhciBhMiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogW107XG4gIHZhciBpc0FsaWduUG9pbnQgPSBhcmd1bWVudHMubGVuZ3RoID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzQWxpZ25Qb2ludCkge1xuICAgIHJldHVybiBhMVswXSA9PT0gYTJbMF07XG4gIH1cbiAgcmV0dXJuIGExWzBdID09PSBhMlswXSAmJiBhMVsxXSA9PT0gYTJbMV07XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxpZ25Qb3B1cENsYXNzTmFtZShidWlsdGluUGxhY2VtZW50cywgcHJlZml4Q2xzLCBhbGlnbiwgaXNBbGlnblBvaW50KSB7XG4gIHZhciBwb2ludHMgPSBhbGlnbi5wb2ludHM7XG4gIHZhciBwbGFjZW1lbnRzID0gT2JqZWN0LmtleXMoYnVpbHRpblBsYWNlbWVudHMpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHBsYWNlbWVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICB2YXIgX2J1aWx0aW5QbGFjZW1lbnRzJHBsO1xuICAgIHZhciBwbGFjZW1lbnQgPSBwbGFjZW1lbnRzW2ldO1xuICAgIGlmIChpc1BvaW50c0VxKChfYnVpbHRpblBsYWNlbWVudHMkcGwgPSBidWlsdGluUGxhY2VtZW50c1twbGFjZW1lbnRdKSA9PT0gbnVsbCB8fCBfYnVpbHRpblBsYWNlbWVudHMkcGwgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9idWlsdGluUGxhY2VtZW50cyRwbC5wb2ludHMsIHBvaW50cywgaXNBbGlnblBvaW50KSkge1xuICAgICAgcmV0dXJuIFwiXCIuY29uY2F0KHByZWZpeENscywgXCItcGxhY2VtZW50LVwiKS5jb25jYXQocGxhY2VtZW50KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICcnO1xufVxuXG4vKiogQGRlcHJlY2F0ZWQgV2Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBpZiB3ZSBjYW4gcmVmYWN0b3IgYWxsIGRlcHMgKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNb3Rpb24ocHJlZml4Q2xzLCBtb3Rpb24sIGFuaW1hdGlvbiwgdHJhbnNpdGlvbk5hbWUpIHtcbiAgaWYgKG1vdGlvbikge1xuICAgIHJldHVybiBtb3Rpb247XG4gIH1cbiAgaWYgKGFuaW1hdGlvbikge1xuICAgIHJldHVybiB7XG4gICAgICBtb3Rpb25OYW1lOiBcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLVwiKS5jb25jYXQoYW5pbWF0aW9uKVxuICAgIH07XG4gIH1cbiAgaWYgKHRyYW5zaXRpb25OYW1lKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vdGlvbk5hbWU6IHRyYW5zaXRpb25OYW1lXG4gICAgfTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRXaW4oZWxlKSB7XG4gIHJldHVybiBlbGUub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldztcbn1cblxuLyoqXG4gKiBHZXQgYWxsIHRoZSBzY3JvbGxhYmxlIHBhcmVudCBlbGVtZW50cyBvZiB0aGUgZWxlbWVudFxuICogQHBhcmFtIGVsZSAgICAgICBUaGUgZWxlbWVudCB0byBiZSBkZXRlY3RlZFxuICogQHBhcmFtIGFyZWFPbmx5ICBPbmx5IHJldHVybiB0aGUgcGFyZW50IHdoaWNoIHdpbGwgY3V0IHZpc2libGUgYXJlYVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdFNjcm9sbGVyKGVsZSkge1xuICB2YXIgc2Nyb2xsZXJMaXN0ID0gW107XG4gIHZhciBjdXJyZW50ID0gZWxlID09PSBudWxsIHx8IGVsZSA9PT0gdm9pZCAwID8gdm9pZCAwIDogZWxlLnBhcmVudEVsZW1lbnQ7XG4gIHZhciBzY3JvbGxTdHlsZSA9IFsnaGlkZGVuJywgJ3Njcm9sbCcsICdjbGlwJywgJ2F1dG8nXTtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICB2YXIgX2dldFdpbiRnZXRDb21wdXRlZFN0ID0gZ2V0V2luKGN1cnJlbnQpLmdldENvbXB1dGVkU3R5bGUoY3VycmVudCksXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0V2luJGdldENvbXB1dGVkU3Qub3ZlcmZsb3dYLFxuICAgICAgb3ZlcmZsb3dZID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Lm92ZXJmbG93WSxcbiAgICAgIG92ZXJmbG93ID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Lm92ZXJmbG93O1xuICAgIGlmIChbb3ZlcmZsb3dYLCBvdmVyZmxvd1ksIG92ZXJmbG93XS5zb21lKGZ1bmN0aW9uIChvKSB7XG4gICAgICByZXR1cm4gc2Nyb2xsU3R5bGUuaW5jbHVkZXMobyk7XG4gICAgfSkpIHtcbiAgICAgIHNjcm9sbGVyTGlzdC5wdXNoKGN1cnJlbnQpO1xuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnRFbGVtZW50O1xuICB9XG4gIHJldHVybiBzY3JvbGxlckxpc3Q7XG59XG5leHBvcnQgZnVuY3Rpb24gdG9OdW0obnVtKSB7XG4gIHZhciBkZWZhdWx0VmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDE7XG4gIHJldHVybiBOdW1iZXIuaXNOYU4obnVtKSA/IGRlZmF1bHRWYWx1ZSA6IG51bTtcbn1cbmZ1bmN0aW9uIGdldFB4VmFsdWUodmFsKSB7XG4gIHJldHVybiB0b051bShwYXJzZUZsb2F0KHZhbCksIDApO1xufVxuLyoqXG4gKlxuICpcbiAqICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICogICAgICAgICAgICAgIEJvcmRlciAgICAgICAgICAgICAgICAqXG4gKiAgKiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICpcbiAqICAqICAgICAqICAgICAgICAgICAgICAgICAgKiAgICAgKiAgICAgKlxuICogICogIEIgICogICAgICAgICAgICAgICAgICAqICBTICAqICBCICAqXG4gKiAgKiAgbyAgKiAgICAgICAgICAgICAgICAgICogIGMgICogIG8gICpcbiAqICAqICByICAqICAgICAgQ29udGVudCAgICAgKiAgciAgKiAgciAgKlxuICogICogIGQgICogICAgICAgICAgICAgICAgICAqICBvICAqICBkICAqXG4gKiAgKiAgZSAgKiAgICAgICAgICAgICAgICAgICogIGwgICogIGUgICpcbiAqICAqICByICAqKioqKioqKioqKioqKioqKioqKiAgbCAgKiAgciAgKlxuICogICogICAgICogICAgICAgIFNjcm9sbCAgICAgICAgICAqICAgICAqXG4gKiAgKiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKiogICAgICpcbiAqICAqICAgICAgICAgICAgICBCb3JkZXIgICAgICAgICAgICAgICAgKlxuICogICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKlxuICovXG4vKipcbiAqIEdldCB2aXNpYmxlIGFyZWEgb2YgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmlzaWJsZUFyZWEoaW5pdEFyZWEsIHNjcm9sbGVyTGlzdCkge1xuICB2YXIgdmlzaWJsZUFyZWEgPSBfb2JqZWN0U3ByZWFkKHt9LCBpbml0QXJlYSk7XG4gIChzY3JvbGxlckxpc3QgfHwgW10pLmZvckVhY2goZnVuY3Rpb24gKGVsZSkge1xuICAgIGlmIChlbGUgaW5zdGFuY2VvZiBIVE1MQm9keUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTa2lwIGlmIHN0YXRpYyBwb3NpdGlvbiB3aGljaCB3aWxsIG5vdCBhZmZlY3QgdmlzaWJsZSBhcmVhXG4gICAgdmFyIF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIgPSBnZXRXaW4oZWxlKS5nZXRDb21wdXRlZFN0eWxlKGVsZSksXG4gICAgICBvdmVyZmxvdyA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd0NsaXBNYXJnaW4gPSBfZ2V0V2luJGdldENvbXB1dGVkU3QyLm92ZXJmbG93Q2xpcE1hcmdpbixcbiAgICAgIGJvcmRlclRvcFdpZHRoID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Mi5ib3JkZXJUb3BXaWR0aCxcbiAgICAgIGJvcmRlckJvdHRvbVdpZHRoID0gX2dldFdpbiRnZXRDb21wdXRlZFN0Mi5ib3JkZXJCb3R0b21XaWR0aCxcbiAgICAgIGJvcmRlckxlZnRXaWR0aCA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIuYm9yZGVyTGVmdFdpZHRoLFxuICAgICAgYm9yZGVyUmlnaHRXaWR0aCA9IF9nZXRXaW4kZ2V0Q29tcHV0ZWRTdDIuYm9yZGVyUmlnaHRXaWR0aDtcbiAgICB2YXIgZWxlUmVjdCA9IGVsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB2YXIgZWxlT3V0SGVpZ2h0ID0gZWxlLm9mZnNldEhlaWdodCxcbiAgICAgIGVsZUlubmVySGVpZ2h0ID0gZWxlLmNsaWVudEhlaWdodCxcbiAgICAgIGVsZU91dFdpZHRoID0gZWxlLm9mZnNldFdpZHRoLFxuICAgICAgZWxlSW5uZXJXaWR0aCA9IGVsZS5jbGllbnRXaWR0aDtcbiAgICB2YXIgYm9yZGVyVG9wTnVtID0gZ2V0UHhWYWx1ZShib3JkZXJUb3BXaWR0aCk7XG4gICAgdmFyIGJvcmRlckJvdHRvbU51bSA9IGdldFB4VmFsdWUoYm9yZGVyQm90dG9tV2lkdGgpO1xuICAgIHZhciBib3JkZXJMZWZ0TnVtID0gZ2V0UHhWYWx1ZShib3JkZXJMZWZ0V2lkdGgpO1xuICAgIHZhciBib3JkZXJSaWdodE51bSA9IGdldFB4VmFsdWUoYm9yZGVyUmlnaHRXaWR0aCk7XG4gICAgdmFyIHNjYWxlWCA9IHRvTnVtKE1hdGgucm91bmQoZWxlUmVjdC53aWR0aCAvIGVsZU91dFdpZHRoICogMTAwMCkgLyAxMDAwKTtcbiAgICB2YXIgc2NhbGVZID0gdG9OdW0oTWF0aC5yb3VuZChlbGVSZWN0LmhlaWdodCAvIGVsZU91dEhlaWdodCAqIDEwMDApIC8gMTAwMCk7XG5cbiAgICAvLyBPcmlnaW5hbCB2aXNpYmxlIGFyZWFcbiAgICB2YXIgZWxlU2Nyb2xsV2lkdGggPSAoZWxlT3V0V2lkdGggLSBlbGVJbm5lcldpZHRoIC0gYm9yZGVyTGVmdE51bSAtIGJvcmRlclJpZ2h0TnVtKSAqIHNjYWxlWDtcbiAgICB2YXIgZWxlU2Nyb2xsSGVpZ2h0ID0gKGVsZU91dEhlaWdodCAtIGVsZUlubmVySGVpZ2h0IC0gYm9yZGVyVG9wTnVtIC0gYm9yZGVyQm90dG9tTnVtKSAqIHNjYWxlWTtcblxuICAgIC8vIEN1dCBib3JkZXIgc2l6ZVxuICAgIHZhciBzY2FsZWRCb3JkZXJUb3BXaWR0aCA9IGJvcmRlclRvcE51bSAqIHNjYWxlWTtcbiAgICB2YXIgc2NhbGVkQm9yZGVyQm90dG9tV2lkdGggPSBib3JkZXJCb3R0b21OdW0gKiBzY2FsZVk7XG4gICAgdmFyIHNjYWxlZEJvcmRlckxlZnRXaWR0aCA9IGJvcmRlckxlZnROdW0gKiBzY2FsZVg7XG4gICAgdmFyIHNjYWxlZEJvcmRlclJpZ2h0V2lkdGggPSBib3JkZXJSaWdodE51bSAqIHNjYWxlWDtcblxuICAgIC8vIENsaXAgbWFyZ2luXG4gICAgdmFyIGNsaXBNYXJnaW5XaWR0aCA9IDA7XG4gICAgdmFyIGNsaXBNYXJnaW5IZWlnaHQgPSAwO1xuICAgIGlmIChvdmVyZmxvdyA9PT0gJ2NsaXAnKSB7XG4gICAgICB2YXIgY2xpcE51bSA9IGdldFB4VmFsdWUob3ZlcmZsb3dDbGlwTWFyZ2luKTtcbiAgICAgIGNsaXBNYXJnaW5XaWR0aCA9IGNsaXBOdW0gKiBzY2FsZVg7XG4gICAgICBjbGlwTWFyZ2luSGVpZ2h0ID0gY2xpcE51bSAqIHNjYWxlWTtcbiAgICB9XG5cbiAgICAvLyBSZWdpb25cbiAgICB2YXIgZWxlTGVmdCA9IGVsZVJlY3QueCArIHNjYWxlZEJvcmRlckxlZnRXaWR0aCAtIGNsaXBNYXJnaW5XaWR0aDtcbiAgICB2YXIgZWxlVG9wID0gZWxlUmVjdC55ICsgc2NhbGVkQm9yZGVyVG9wV2lkdGggLSBjbGlwTWFyZ2luSGVpZ2h0O1xuICAgIHZhciBlbGVSaWdodCA9IGVsZUxlZnQgKyBlbGVSZWN0LndpZHRoICsgMiAqIGNsaXBNYXJnaW5XaWR0aCAtIHNjYWxlZEJvcmRlckxlZnRXaWR0aCAtIHNjYWxlZEJvcmRlclJpZ2h0V2lkdGggLSBlbGVTY3JvbGxXaWR0aDtcbiAgICB2YXIgZWxlQm90dG9tID0gZWxlVG9wICsgZWxlUmVjdC5oZWlnaHQgKyAyICogY2xpcE1hcmdpbkhlaWdodCAtIHNjYWxlZEJvcmRlclRvcFdpZHRoIC0gc2NhbGVkQm9yZGVyQm90dG9tV2lkdGggLSBlbGVTY3JvbGxIZWlnaHQ7XG4gICAgdmlzaWJsZUFyZWEubGVmdCA9IE1hdGgubWF4KHZpc2libGVBcmVhLmxlZnQsIGVsZUxlZnQpO1xuICAgIHZpc2libGVBcmVhLnRvcCA9IE1hdGgubWF4KHZpc2libGVBcmVhLnRvcCwgZWxlVG9wKTtcbiAgICB2aXNpYmxlQXJlYS5yaWdodCA9IE1hdGgubWluKHZpc2libGVBcmVhLnJpZ2h0LCBlbGVSaWdodCk7XG4gICAgdmlzaWJsZUFyZWEuYm90dG9tID0gTWF0aC5taW4odmlzaWJsZUFyZWEuYm90dG9tLCBlbGVCb3R0b20pO1xuICB9KTtcbiAgcmV0dXJuIHZpc2libGVBcmVhO1xufSIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCB7IGlzRE9NIH0gZnJvbSBcInJjLXV0aWwvZXMvRG9tL2ZpbmRET01Ob2RlXCI7XG5pbXBvcnQgaXNWaXNpYmxlIGZyb20gXCJyYy11dGlsL2VzL0RvbS9pc1Zpc2libGVcIjtcbmltcG9ydCB1c2VFdmVudCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VFdmVudFwiO1xuaW1wb3J0IHVzZUxheW91dEVmZmVjdCBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VMYXlvdXRFZmZlY3RcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IGNvbGxlY3RTY3JvbGxlciwgZ2V0VmlzaWJsZUFyZWEsIGdldFdpbiwgdG9OdW0gfSBmcm9tIFwiLi4vdXRpbFwiO1xuZnVuY3Rpb24gZ2V0VW5pdE9mZnNldChzaXplKSB7XG4gIHZhciBvZmZzZXQgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7XG4gIHZhciBvZmZzZXRTdHIgPSBcIlwiLmNvbmNhdChvZmZzZXQpO1xuICB2YXIgY2VsbHMgPSBvZmZzZXRTdHIubWF0Y2goL14oLiopXFwlJC8pO1xuICBpZiAoY2VsbHMpIHtcbiAgICByZXR1cm4gc2l6ZSAqIChwYXJzZUZsb2F0KGNlbGxzWzFdKSAvIDEwMCk7XG4gIH1cbiAgcmV0dXJuIHBhcnNlRmxvYXQob2Zmc2V0U3RyKTtcbn1cbmZ1bmN0aW9uIGdldE51bWJlck9mZnNldChyZWN0LCBvZmZzZXQpIHtcbiAgdmFyIF9yZWYgPSBvZmZzZXQgfHwgW10sXG4gICAgX3JlZjIgPSBfc2xpY2VkVG9BcnJheShfcmVmLCAyKSxcbiAgICBvZmZzZXRYID0gX3JlZjJbMF0sXG4gICAgb2Zmc2V0WSA9IF9yZWYyWzFdO1xuICByZXR1cm4gW2dldFVuaXRPZmZzZXQocmVjdC53aWR0aCwgb2Zmc2V0WCksIGdldFVuaXRPZmZzZXQocmVjdC5oZWlnaHQsIG9mZnNldFkpXTtcbn1cbmZ1bmN0aW9uIHNwbGl0UG9pbnRzKCkge1xuICB2YXIgcG9pbnRzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiAnJztcbiAgcmV0dXJuIFtwb2ludHNbMF0sIHBvaW50c1sxXV07XG59XG5mdW5jdGlvbiBnZXRBbGlnblBvaW50KHJlY3QsIHBvaW50cykge1xuICB2YXIgdG9wQm90dG9tID0gcG9pbnRzWzBdO1xuICB2YXIgbGVmdFJpZ2h0ID0gcG9pbnRzWzFdO1xuICB2YXIgeDtcbiAgdmFyIHk7XG5cbiAgLy8gVG9wICYgQm90dG9tXG4gIGlmICh0b3BCb3R0b20gPT09ICd0Jykge1xuICAgIHkgPSByZWN0Lnk7XG4gIH0gZWxzZSBpZiAodG9wQm90dG9tID09PSAnYicpIHtcbiAgICB5ID0gcmVjdC55ICsgcmVjdC5oZWlnaHQ7XG4gIH0gZWxzZSB7XG4gICAgeSA9IHJlY3QueSArIHJlY3QuaGVpZ2h0IC8gMjtcbiAgfVxuXG4gIC8vIExlZnQgJiBSaWdodFxuICBpZiAobGVmdFJpZ2h0ID09PSAnbCcpIHtcbiAgICB4ID0gcmVjdC54O1xuICB9IGVsc2UgaWYgKGxlZnRSaWdodCA9PT0gJ3InKSB7XG4gICAgeCA9IHJlY3QueCArIHJlY3Qud2lkdGg7XG4gIH0gZWxzZSB7XG4gICAgeCA9IHJlY3QueCArIHJlY3Qud2lkdGggLyAyO1xuICB9XG4gIHJldHVybiB7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG59XG5mdW5jdGlvbiByZXZlcnNlUG9pbnRzKHBvaW50cywgaW5kZXgpIHtcbiAgdmFyIHJldmVyc2VNYXAgPSB7XG4gICAgdDogJ2InLFxuICAgIGI6ICd0JyxcbiAgICBsOiAncicsXG4gICAgcjogJ2wnXG4gIH07XG4gIHJldHVybiBwb2ludHMubWFwKGZ1bmN0aW9uIChwb2ludCwgaSkge1xuICAgIGlmIChpID09PSBpbmRleCkge1xuICAgICAgcmV0dXJuIHJldmVyc2VNYXBbcG9pbnRdIHx8ICdjJztcbiAgICB9XG4gICAgcmV0dXJuIHBvaW50O1xuICB9KS5qb2luKCcnKTtcbn1cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZUFsaWduKG9wZW4sIHBvcHVwRWxlLCB0YXJnZXQsIHBsYWNlbWVudCwgYnVpbHRpblBsYWNlbWVudHMsIHBvcHVwQWxpZ24sIG9uUG9wdXBBbGlnbikge1xuICB2YXIgX1JlYWN0JHVzZVN0YXRlID0gUmVhY3QudXNlU3RhdGUoe1xuICAgICAgcmVhZHk6IGZhbHNlLFxuICAgICAgb2Zmc2V0WDogMCxcbiAgICAgIG9mZnNldFk6IDAsXG4gICAgICBhcnJvd1g6IDAsXG4gICAgICBhcnJvd1k6IDAsXG4gICAgICBzY2FsZVg6IDEsXG4gICAgICBzY2FsZVk6IDEsXG4gICAgICBhbGlnbjogYnVpbHRpblBsYWNlbWVudHNbcGxhY2VtZW50XSB8fCB7fVxuICAgIH0pLFxuICAgIF9SZWFjdCR1c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUsIDIpLFxuICAgIG9mZnNldEluZm8gPSBfUmVhY3QkdXNlU3RhdGUyWzBdLFxuICAgIHNldE9mZnNldEluZm8gPSBfUmVhY3QkdXNlU3RhdGUyWzFdO1xuICB2YXIgYWxpZ25Db3VudFJlZiA9IFJlYWN0LnVzZVJlZigwKTtcbiAgdmFyIHNjcm9sbGVyTGlzdCA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIGlmICghcG9wdXBFbGUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbGxlY3RTY3JvbGxlcihwb3B1cEVsZSk7XG4gIH0sIFtwb3B1cEVsZV0pO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT0gRmxpcCA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBXZSB3aWxsIG1lbW8gZmxpcCBpbmZvLlxuICAvLyBJZiBzaXplIGNoYW5nZSB0byBtYWtlIGZsaXAsIGl0IHdpbGwgbWVtbyB0aGUgZmxpcCBpbmZvIGFuZCB1c2UgaXQgaW4gbmV4dCBhbGlnbi5cbiAgdmFyIHByZXZGbGlwUmVmID0gUmVhY3QudXNlUmVmKHt9KTtcbiAgdmFyIHJlc2V0RmxpcENhY2hlID0gZnVuY3Rpb24gcmVzZXRGbGlwQ2FjaGUoKSB7XG4gICAgcHJldkZsaXBSZWYuY3VycmVudCA9IHt9O1xuICB9O1xuICBpZiAoIW9wZW4pIHtcbiAgICByZXNldEZsaXBDYWNoZSgpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBBbGlnbiA9PT09PT09PT09PT09PT09PT09PT09PT09XG4gIHZhciBvbkFsaWduID0gdXNlRXZlbnQoZnVuY3Rpb24gKCkge1xuICAgIGlmIChwb3B1cEVsZSAmJiB0YXJnZXQgJiYgb3Blbikge1xuICAgICAgdmFyIHBvcHVwRWxlbWVudCA9IHBvcHVwRWxlO1xuICAgICAgdmFyIG9yaWdpbkxlZnQgPSBwb3B1cEVsZW1lbnQuc3R5bGUubGVmdDtcbiAgICAgIHZhciBvcmlnaW5Ub3AgPSBwb3B1cEVsZW1lbnQuc3R5bGUudG9wO1xuICAgICAgdmFyIGRvYyA9IHBvcHVwRWxlbWVudC5vd25lckRvY3VtZW50O1xuICAgICAgdmFyIHdpbiA9IGdldFdpbihwb3B1cEVsZW1lbnQpO1xuXG4gICAgICAvLyBQbGFjZW1lbnRcbiAgICAgIHZhciBwbGFjZW1lbnRJbmZvID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBidWlsdGluUGxhY2VtZW50c1twbGFjZW1lbnRdKSwgcG9wdXBBbGlnbik7XG5cbiAgICAgIC8vIFJlc2V0IGZpcnN0XG4gICAgICBwb3B1cEVsZW1lbnQuc3R5bGUubGVmdCA9ICcwJztcbiAgICAgIHBvcHVwRWxlbWVudC5zdHlsZS50b3AgPSAnMCc7XG5cbiAgICAgIC8vIENhbGN1bGF0ZSBhbGlnbiBzdHlsZSwgd2Ugc2hvdWxkIGNvbnNpZGVyIGB0cmFuc2Zvcm1gIGNhc2VcbiAgICAgIHZhciB0YXJnZXRSZWN0O1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGFyZ2V0KSkge1xuICAgICAgICB0YXJnZXRSZWN0ID0ge1xuICAgICAgICAgIHg6IHRhcmdldFswXSxcbiAgICAgICAgICB5OiB0YXJnZXRbMV0sXG4gICAgICAgICAgd2lkdGg6IDAsXG4gICAgICAgICAgaGVpZ2h0OiAwXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcmVjdCA9IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgdGFyZ2V0UmVjdCA9IHtcbiAgICAgICAgICB4OiByZWN0LngsXG4gICAgICAgICAgeTogcmVjdC55LFxuICAgICAgICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgICAgICAgIGhlaWdodDogcmVjdC5oZWlnaHRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHZhciBwb3B1cFJlY3QgPSBwb3B1cEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB2YXIgX3dpbiRnZXRDb21wdXRlZFN0eWxlID0gd2luLmdldENvbXB1dGVkU3R5bGUocG9wdXBFbGVtZW50KSxcbiAgICAgICAgd2lkdGggPSBfd2luJGdldENvbXB1dGVkU3R5bGUud2lkdGgsXG4gICAgICAgIGhlaWdodCA9IF93aW4kZ2V0Q29tcHV0ZWRTdHlsZS5oZWlnaHQ7XG4gICAgICB2YXIgX2RvYyRkb2N1bWVudEVsZW1lbnQgPSBkb2MuZG9jdW1lbnRFbGVtZW50LFxuICAgICAgICBjbGllbnRXaWR0aCA9IF9kb2MkZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoLFxuICAgICAgICBjbGllbnRIZWlnaHQgPSBfZG9jJGRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQsXG4gICAgICAgIHNjcm9sbFdpZHRoID0gX2RvYyRkb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGgsXG4gICAgICAgIHNjcm9sbEhlaWdodCA9IF9kb2MkZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodCxcbiAgICAgICAgc2Nyb2xsVG9wID0gX2RvYyRkb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wLFxuICAgICAgICBzY3JvbGxMZWZ0ID0gX2RvYyRkb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdDtcbiAgICAgIHZhciBwb3B1cEhlaWdodCA9IHBvcHVwUmVjdC5oZWlnaHQ7XG4gICAgICB2YXIgcG9wdXBXaWR0aCA9IHBvcHVwUmVjdC53aWR0aDtcbiAgICAgIHZhciB0YXJnZXRIZWlnaHQgPSB0YXJnZXRSZWN0LmhlaWdodDtcbiAgICAgIHZhciB0YXJnZXRXaWR0aCA9IHRhcmdldFJlY3Qud2lkdGg7XG5cbiAgICAgIC8vIEdldCBib3VuZGluZyBvZiB2aXNpYmxlIGFyZWFcbiAgICAgIHZhciB2aXNpYmxlQXJlYSA9IHBsYWNlbWVudEluZm8uaHRtbFJlZ2lvbiA9PT0gJ3Njcm9sbCcgP1xuICAgICAgLy8gU2Nyb2xsIHJlZ2lvbiBzaG91bGQgdGFrZSBzY3JvbGxMZWZ0ICYgc2Nyb2xsVG9wIGludG8gYWNjb3VudFxuICAgICAge1xuICAgICAgICBsZWZ0OiAtc2Nyb2xsTGVmdCxcbiAgICAgICAgdG9wOiAtc2Nyb2xsVG9wLFxuICAgICAgICByaWdodDogc2Nyb2xsV2lkdGggLSBzY3JvbGxMZWZ0LFxuICAgICAgICBib3R0b206IHNjcm9sbEhlaWdodCAtIHNjcm9sbFRvcFxuICAgICAgfSA6IHtcbiAgICAgICAgbGVmdDogMCxcbiAgICAgICAgdG9wOiAwLFxuICAgICAgICByaWdodDogY2xpZW50V2lkdGgsXG4gICAgICAgIGJvdHRvbTogY2xpZW50SGVpZ2h0XG4gICAgICB9O1xuICAgICAgdmlzaWJsZUFyZWEgPSBnZXRWaXNpYmxlQXJlYSh2aXNpYmxlQXJlYSwgc2Nyb2xsZXJMaXN0KTtcblxuICAgICAgLy8gUmVzZXQgYmFja1xuICAgICAgcG9wdXBFbGVtZW50LnN0eWxlLmxlZnQgPSBvcmlnaW5MZWZ0O1xuICAgICAgcG9wdXBFbGVtZW50LnN0eWxlLnRvcCA9IG9yaWdpblRvcDtcblxuICAgICAgLy8gQ2FsY3VsYXRlIHNjYWxlXG4gICAgICB2YXIgX3NjYWxlWCA9IHRvTnVtKE1hdGgucm91bmQocG9wdXBXaWR0aCAvIHBhcnNlRmxvYXQod2lkdGgpICogMTAwMCkgLyAxMDAwKTtcbiAgICAgIHZhciBfc2NhbGVZID0gdG9OdW0oTWF0aC5yb3VuZChwb3B1cEhlaWdodCAvIHBhcnNlRmxvYXQoaGVpZ2h0KSAqIDEwMDApIC8gMTAwMCk7XG5cbiAgICAgIC8vIE5vIG5lZWQgdG8gYWxpZ24gc2luY2UgaXQncyBub3QgdmlzaWJsZSBpbiB2aWV3XG4gICAgICBpZiAoX3NjYWxlWCA9PT0gMCB8fCBfc2NhbGVZID09PSAwIHx8IGlzRE9NKHRhcmdldCkgJiYgIWlzVmlzaWJsZSh0YXJnZXQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gT2Zmc2V0XG4gICAgICB2YXIgb2Zmc2V0ID0gcGxhY2VtZW50SW5mby5vZmZzZXQsXG4gICAgICAgIHRhcmdldE9mZnNldCA9IHBsYWNlbWVudEluZm8udGFyZ2V0T2Zmc2V0O1xuICAgICAgdmFyIF9nZXROdW1iZXJPZmZzZXQgPSBnZXROdW1iZXJPZmZzZXQocG9wdXBSZWN0LCBvZmZzZXQpLFxuICAgICAgICBfZ2V0TnVtYmVyT2Zmc2V0MiA9IF9zbGljZWRUb0FycmF5KF9nZXROdW1iZXJPZmZzZXQsIDIpLFxuICAgICAgICBwb3B1cE9mZnNldFggPSBfZ2V0TnVtYmVyT2Zmc2V0MlswXSxcbiAgICAgICAgcG9wdXBPZmZzZXRZID0gX2dldE51bWJlck9mZnNldDJbMV07XG4gICAgICB2YXIgX2dldE51bWJlck9mZnNldDMgPSBnZXROdW1iZXJPZmZzZXQodGFyZ2V0UmVjdCwgdGFyZ2V0T2Zmc2V0KSxcbiAgICAgICAgX2dldE51bWJlck9mZnNldDQgPSBfc2xpY2VkVG9BcnJheShfZ2V0TnVtYmVyT2Zmc2V0MywgMiksXG4gICAgICAgIHRhcmdldE9mZnNldFggPSBfZ2V0TnVtYmVyT2Zmc2V0NFswXSxcbiAgICAgICAgdGFyZ2V0T2Zmc2V0WSA9IF9nZXROdW1iZXJPZmZzZXQ0WzFdO1xuICAgICAgdGFyZ2V0UmVjdC54IC09IHRhcmdldE9mZnNldFg7XG4gICAgICB0YXJnZXRSZWN0LnkgLT0gdGFyZ2V0T2Zmc2V0WTtcblxuICAgICAgLy8gUG9pbnRzXG4gICAgICB2YXIgX3JlZjMgPSBwbGFjZW1lbnRJbmZvLnBvaW50cyB8fCBbXSxcbiAgICAgICAgX3JlZjQgPSBfc2xpY2VkVG9BcnJheShfcmVmMywgMiksXG4gICAgICAgIHBvcHVwUG9pbnQgPSBfcmVmNFswXSxcbiAgICAgICAgdGFyZ2V0UG9pbnQgPSBfcmVmNFsxXTtcbiAgICAgIHZhciB0YXJnZXRQb2ludHMgPSBzcGxpdFBvaW50cyh0YXJnZXRQb2ludCk7XG4gICAgICB2YXIgcG9wdXBQb2ludHMgPSBzcGxpdFBvaW50cyhwb3B1cFBvaW50KTtcbiAgICAgIHZhciB0YXJnZXRBbGlnblBvaW50ID0gZ2V0QWxpZ25Qb2ludCh0YXJnZXRSZWN0LCB0YXJnZXRQb2ludHMpO1xuICAgICAgdmFyIHBvcHVwQWxpZ25Qb2ludCA9IGdldEFsaWduUG9pbnQocG9wdXBSZWN0LCBwb3B1cFBvaW50cyk7XG5cbiAgICAgIC8vIFJlYWwgYWxpZ24gaW5mbyBtYXkgbm90IHNhbWUgYXMgb3JpZ2luIG9uZVxuICAgICAgdmFyIG5leHRBbGlnbkluZm8gPSBfb2JqZWN0U3ByZWFkKHt9LCBwbGFjZW1lbnRJbmZvKTtcblxuICAgICAgLy8gTmV4dCBPZmZzZXRcbiAgICAgIHZhciBuZXh0T2Zmc2V0WCA9IHRhcmdldEFsaWduUG9pbnQueCAtIHBvcHVwQWxpZ25Qb2ludC54ICsgcG9wdXBPZmZzZXRYO1xuICAgICAgdmFyIG5leHRPZmZzZXRZID0gdGFyZ2V0QWxpZ25Qb2ludC55IC0gcG9wdXBBbGlnblBvaW50LnkgKyBwb3B1cE9mZnNldFk7XG5cbiAgICAgIC8vID09PT09PT09PT09PT09IEludGVyc2VjdGlvbiA9PT09PT09PT09PT09PT1cbiAgICAgIC8vIEdldCBhcmVhIGJ5IHBvc2l0aW9uLiBVc2VkIGZvciBjaGVjayBpZiBmbGlwIGFyZWEgaXMgYmV0dGVyXG4gICAgICBmdW5jdGlvbiBnZXRJbnRlcnNlY3Rpb25WaXNpYmxlQXJlYShvZmZzZXRYLCBvZmZzZXRZKSB7XG4gICAgICAgIHZhciBsID0gcG9wdXBSZWN0LnggKyBvZmZzZXRYO1xuICAgICAgICB2YXIgdCA9IHBvcHVwUmVjdC55ICsgb2Zmc2V0WTtcbiAgICAgICAgdmFyIHIgPSBsICsgcG9wdXBXaWR0aDtcbiAgICAgICAgdmFyIGIgPSB0ICsgcG9wdXBIZWlnaHQ7XG4gICAgICAgIHZhciB2aXNpYmxlTCA9IE1hdGgubWF4KGwsIHZpc2libGVBcmVhLmxlZnQpO1xuICAgICAgICB2YXIgdmlzaWJsZVQgPSBNYXRoLm1heCh0LCB2aXNpYmxlQXJlYS50b3ApO1xuICAgICAgICB2YXIgdmlzaWJsZVIgPSBNYXRoLm1pbihyLCB2aXNpYmxlQXJlYS5yaWdodCk7XG4gICAgICAgIHZhciB2aXNpYmxlQiA9IE1hdGgubWluKGIsIHZpc2libGVBcmVhLmJvdHRvbSk7XG4gICAgICAgIHJldHVybiBNYXRoLm1heCgwLCAodmlzaWJsZVIgLSB2aXNpYmxlTCkgKiAodmlzaWJsZUIgLSB2aXNpYmxlVCkpO1xuICAgICAgfVxuICAgICAgdmFyIG9yaWdpbkludGVyc2VjdGlvblZpc2libGVBcmVhID0gZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEobmV4dE9mZnNldFgsIG5leHRPZmZzZXRZKTtcblxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gT3ZlcmZsb3cgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICB2YXIgdGFyZ2V0QWxpZ25Qb2ludFRMID0gZ2V0QWxpZ25Qb2ludCh0YXJnZXRSZWN0LCBbJ3QnLCAnbCddKTtcbiAgICAgIHZhciBwb3B1cEFsaWduUG9pbnRUTCA9IGdldEFsaWduUG9pbnQocG9wdXBSZWN0LCBbJ3QnLCAnbCddKTtcbiAgICAgIHZhciB0YXJnZXRBbGlnblBvaW50QlIgPSBnZXRBbGlnblBvaW50KHRhcmdldFJlY3QsIFsnYicsICdyJ10pO1xuICAgICAgdmFyIHBvcHVwQWxpZ25Qb2ludEJSID0gZ2V0QWxpZ25Qb2ludChwb3B1cFJlY3QsIFsnYicsICdyJ10pO1xuICAgICAgdmFyIG92ZXJmbG93ID0gcGxhY2VtZW50SW5mby5vdmVyZmxvdyB8fCB7fTtcbiAgICAgIHZhciBhZGp1c3RYID0gb3ZlcmZsb3cuYWRqdXN0WCxcbiAgICAgICAgYWRqdXN0WSA9IG92ZXJmbG93LmFkanVzdFksXG4gICAgICAgIHNoaWZ0WCA9IG92ZXJmbG93LnNoaWZ0WCxcbiAgICAgICAgc2hpZnRZID0gb3ZlcmZsb3cuc2hpZnRZO1xuICAgICAgdmFyIHN1cHBvcnRBZGp1c3QgPSBmdW5jdGlvbiBzdXBwb3J0QWRqdXN0KHZhbCkge1xuICAgICAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsID49IDA7XG4gICAgICB9O1xuXG4gICAgICAvLyBQcmVwYXJlIHBvc2l0aW9uXG4gICAgICB2YXIgbmV4dFBvcHVwWTtcbiAgICAgIHZhciBuZXh0UG9wdXBCb3R0b207XG4gICAgICB2YXIgbmV4dFBvcHVwWDtcbiAgICAgIHZhciBuZXh0UG9wdXBSaWdodDtcbiAgICAgIGZ1bmN0aW9uIHN5bmNOZXh0UG9wdXBQb3NpdGlvbigpIHtcbiAgICAgICAgbmV4dFBvcHVwWSA9IHBvcHVwUmVjdC55ICsgbmV4dE9mZnNldFk7XG4gICAgICAgIG5leHRQb3B1cEJvdHRvbSA9IG5leHRQb3B1cFkgKyBwb3B1cEhlaWdodDtcbiAgICAgICAgbmV4dFBvcHVwWCA9IHBvcHVwUmVjdC54ICsgbmV4dE9mZnNldFg7XG4gICAgICAgIG5leHRQb3B1cFJpZ2h0ID0gbmV4dFBvcHVwWCArIHBvcHVwV2lkdGg7XG4gICAgICB9XG4gICAgICBzeW5jTmV4dFBvcHVwUG9zaXRpb24oKTtcblxuICAgICAgLy8gPj4+Pj4+Pj4+PiBUb3AgJiBCb3R0b21cbiAgICAgIHZhciBuZWVkQWRqdXN0WSA9IHN1cHBvcnRBZGp1c3QoYWRqdXN0WSk7XG4gICAgICB2YXIgc2FtZVRCID0gcG9wdXBQb2ludHNbMF0gPT09IHRhcmdldFBvaW50c1swXTtcblxuICAgICAgLy8gQm90dG9tIHRvIFRvcFxuICAgICAgaWYgKG5lZWRBZGp1c3RZICYmIHBvcHVwUG9pbnRzWzBdID09PSAndCcgJiYgKG5leHRQb3B1cEJvdHRvbSA+IHZpc2libGVBcmVhLmJvdHRvbSB8fCBwcmV2RmxpcFJlZi5jdXJyZW50LmJ0KSkge1xuICAgICAgICB2YXIgdG1wTmV4dE9mZnNldFkgPSBuZXh0T2Zmc2V0WTtcbiAgICAgICAgaWYgKHNhbWVUQikge1xuICAgICAgICAgIHRtcE5leHRPZmZzZXRZIC09IHBvcHVwSGVpZ2h0IC0gdGFyZ2V0SGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRtcE5leHRPZmZzZXRZID0gdGFyZ2V0QWxpZ25Qb2ludFRMLnkgLSBwb3B1cEFsaWduUG9pbnRCUi55IC0gcG9wdXBPZmZzZXRZO1xuICAgICAgICB9XG4gICAgICAgIGlmIChnZXRJbnRlcnNlY3Rpb25WaXNpYmxlQXJlYShuZXh0T2Zmc2V0WCwgdG1wTmV4dE9mZnNldFkpID49IG9yaWdpbkludGVyc2VjdGlvblZpc2libGVBcmVhKSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC5idCA9IHRydWU7XG4gICAgICAgICAgbmV4dE9mZnNldFkgPSB0bXBOZXh0T2Zmc2V0WTtcbiAgICAgICAgICBuZXh0QWxpZ25JbmZvLnBvaW50cyA9IFtyZXZlcnNlUG9pbnRzKHBvcHVwUG9pbnRzLCAwKSwgcmV2ZXJzZVBvaW50cyh0YXJnZXRQb2ludHMsIDApXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LmJ0ID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVG9wIHRvIEJvdHRvbVxuICAgICAgaWYgKG5lZWRBZGp1c3RZICYmIHBvcHVwUG9pbnRzWzBdID09PSAnYicgJiYgKG5leHRQb3B1cFkgPCB2aXNpYmxlQXJlYS50b3AgfHwgcHJldkZsaXBSZWYuY3VycmVudC50YikpIHtcbiAgICAgICAgdmFyIF90bXBOZXh0T2Zmc2V0WSA9IG5leHRPZmZzZXRZO1xuICAgICAgICBpZiAoc2FtZVRCKSB7XG4gICAgICAgICAgX3RtcE5leHRPZmZzZXRZICs9IHBvcHVwSGVpZ2h0IC0gdGFyZ2V0SGVpZ2h0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF90bXBOZXh0T2Zmc2V0WSA9IHRhcmdldEFsaWduUG9pbnRCUi55IC0gcG9wdXBBbGlnblBvaW50VEwueSAtIHBvcHVwT2Zmc2V0WTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEobmV4dE9mZnNldFgsIF90bXBOZXh0T2Zmc2V0WSkgPj0gb3JpZ2luSW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEpIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LnRiID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0T2Zmc2V0WSA9IF90bXBOZXh0T2Zmc2V0WTtcbiAgICAgICAgICBuZXh0QWxpZ25JbmZvLnBvaW50cyA9IFtyZXZlcnNlUG9pbnRzKHBvcHVwUG9pbnRzLCAwKSwgcmV2ZXJzZVBvaW50cyh0YXJnZXRQb2ludHMsIDApXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LnRiID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gPj4+Pj4+Pj4+PiBMZWZ0ICYgUmlnaHRcbiAgICAgIHZhciBuZWVkQWRqdXN0WCA9IHN1cHBvcnRBZGp1c3QoYWRqdXN0WCk7XG5cbiAgICAgIC8vID4+Pj4+IEZsaXBcbiAgICAgIHZhciBzYW1lTFIgPSBwb3B1cFBvaW50c1sxXSA9PT0gdGFyZ2V0UG9pbnRzWzFdO1xuXG4gICAgICAvLyBSaWdodCB0byBMZWZ0XG4gICAgICBpZiAobmVlZEFkanVzdFggJiYgcG9wdXBQb2ludHNbMV0gPT09ICdsJyAmJiAobmV4dFBvcHVwUmlnaHQgPiB2aXNpYmxlQXJlYS5yaWdodCB8fCBwcmV2RmxpcFJlZi5jdXJyZW50LnJsKSkge1xuICAgICAgICB2YXIgdG1wTmV4dE9mZnNldFggPSBuZXh0T2Zmc2V0WDtcbiAgICAgICAgaWYgKHNhbWVMUikge1xuICAgICAgICAgIHRtcE5leHRPZmZzZXRYIC09IHBvcHVwV2lkdGggLSB0YXJnZXRXaWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0bXBOZXh0T2Zmc2V0WCA9IHRhcmdldEFsaWduUG9pbnRUTC54IC0gcG9wdXBBbGlnblBvaW50QlIueCAtIHBvcHVwT2Zmc2V0WDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEodG1wTmV4dE9mZnNldFgsIG5leHRPZmZzZXRZKSA+PSBvcmlnaW5JbnRlcnNlY3Rpb25WaXNpYmxlQXJlYSkge1xuICAgICAgICAgIHByZXZGbGlwUmVmLmN1cnJlbnQucmwgPSB0cnVlO1xuICAgICAgICAgIG5leHRPZmZzZXRYID0gdG1wTmV4dE9mZnNldFg7XG4gICAgICAgICAgbmV4dEFsaWduSW5mby5wb2ludHMgPSBbcmV2ZXJzZVBvaW50cyhwb3B1cFBvaW50cywgMSksIHJldmVyc2VQb2ludHModGFyZ2V0UG9pbnRzLCAxKV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldkZsaXBSZWYuY3VycmVudC5ybCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIExlZnQgdG8gUmlnaHRcbiAgICAgIGlmIChuZWVkQWRqdXN0WCAmJiBwb3B1cFBvaW50c1sxXSA9PT0gJ3InICYmIChuZXh0UG9wdXBYIDwgdmlzaWJsZUFyZWEubGVmdCB8fCBwcmV2RmxpcFJlZi5jdXJyZW50LmxyKSkge1xuICAgICAgICB2YXIgX3RtcE5leHRPZmZzZXRYID0gbmV4dE9mZnNldFg7XG4gICAgICAgIGlmIChzYW1lTFIpIHtcbiAgICAgICAgICBfdG1wTmV4dE9mZnNldFggKz0gcG9wdXBXaWR0aCAtIHRhcmdldFdpZHRoO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF90bXBOZXh0T2Zmc2V0WCA9IHRhcmdldEFsaWduUG9pbnRCUi54IC0gcG9wdXBBbGlnblBvaW50VEwueCAtIHBvcHVwT2Zmc2V0WDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ2V0SW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEoX3RtcE5leHRPZmZzZXRYLCBuZXh0T2Zmc2V0WSkgPj0gb3JpZ2luSW50ZXJzZWN0aW9uVmlzaWJsZUFyZWEpIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LmxyID0gdHJ1ZTtcbiAgICAgICAgICBuZXh0T2Zmc2V0WCA9IF90bXBOZXh0T2Zmc2V0WDtcbiAgICAgICAgICBuZXh0QWxpZ25JbmZvLnBvaW50cyA9IFtyZXZlcnNlUG9pbnRzKHBvcHVwUG9pbnRzLCAxKSwgcmV2ZXJzZVBvaW50cyh0YXJnZXRQb2ludHMsIDEpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwcmV2RmxpcFJlZi5jdXJyZW50LmxyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTaGlmdCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICBzeW5jTmV4dFBvcHVwUG9zaXRpb24oKTtcbiAgICAgIHZhciBudW1TaGlmdFggPSBzaGlmdFggPT09IHRydWUgPyAwIDogc2hpZnRYO1xuICAgICAgaWYgKHR5cGVvZiBudW1TaGlmdFggPT09ICdudW1iZXInKSB7XG4gICAgICAgIC8vIExlZnRcbiAgICAgICAgaWYgKG5leHRQb3B1cFggPCB2aXNpYmxlQXJlYS5sZWZ0KSB7XG4gICAgICAgICAgbmV4dE9mZnNldFggLT0gbmV4dFBvcHVwWCAtIHZpc2libGVBcmVhLmxlZnQ7XG4gICAgICAgICAgaWYgKHRhcmdldFJlY3QueCArIHRhcmdldFdpZHRoIDwgdmlzaWJsZUFyZWEubGVmdCArIG51bVNoaWZ0WCkge1xuICAgICAgICAgICAgbmV4dE9mZnNldFggKz0gdGFyZ2V0UmVjdC54IC0gdmlzaWJsZUFyZWEubGVmdCArIHRhcmdldFdpZHRoIC0gbnVtU2hpZnRYO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJpZ2h0XG4gICAgICAgIGlmIChuZXh0UG9wdXBSaWdodCA+IHZpc2libGVBcmVhLnJpZ2h0KSB7XG4gICAgICAgICAgbmV4dE9mZnNldFggLT0gbmV4dFBvcHVwUmlnaHQgLSB2aXNpYmxlQXJlYS5yaWdodDtcbiAgICAgICAgICBpZiAodGFyZ2V0UmVjdC54ID4gdmlzaWJsZUFyZWEucmlnaHQgLSBudW1TaGlmdFgpIHtcbiAgICAgICAgICAgIG5leHRPZmZzZXRYICs9IHRhcmdldFJlY3QueCAtIHZpc2libGVBcmVhLnJpZ2h0ICsgbnVtU2hpZnRYO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIG51bVNoaWZ0WSA9IHNoaWZ0WSA9PT0gdHJ1ZSA/IDAgOiBzaGlmdFk7XG4gICAgICBpZiAodHlwZW9mIG51bVNoaWZ0WSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgLy8gVG9wXG4gICAgICAgIGlmIChuZXh0UG9wdXBZIDwgdmlzaWJsZUFyZWEudG9wKSB7XG4gICAgICAgICAgbmV4dE9mZnNldFkgLT0gbmV4dFBvcHVwWSAtIHZpc2libGVBcmVhLnRvcDtcbiAgICAgICAgICBpZiAodGFyZ2V0UmVjdC55ICsgdGFyZ2V0SGVpZ2h0IDwgdmlzaWJsZUFyZWEudG9wICsgbnVtU2hpZnRZKSB7XG4gICAgICAgICAgICBuZXh0T2Zmc2V0WSArPSB0YXJnZXRSZWN0LnkgLSB2aXNpYmxlQXJlYS50b3AgKyB0YXJnZXRIZWlnaHQgLSBudW1TaGlmdFk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQm90dG9tXG4gICAgICAgIGlmIChuZXh0UG9wdXBCb3R0b20gPiB2aXNpYmxlQXJlYS5ib3R0b20pIHtcbiAgICAgICAgICBuZXh0T2Zmc2V0WSAtPSBuZXh0UG9wdXBCb3R0b20gLSB2aXNpYmxlQXJlYS5ib3R0b207XG4gICAgICAgICAgaWYgKHRhcmdldFJlY3QueSA+IHZpc2libGVBcmVhLmJvdHRvbSAtIG51bVNoaWZ0WSkge1xuICAgICAgICAgICAgbmV4dE9mZnNldFkgKz0gdGFyZ2V0UmVjdC55IC0gdmlzaWJsZUFyZWEuYm90dG9tICsgbnVtU2hpZnRZO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09IEFycm93ID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgIC8vIEFycm93IGNlbnRlciBhbGlnblxuICAgICAgdmFyIHBvcHVwTGVmdCA9IHBvcHVwUmVjdC54ICsgbmV4dE9mZnNldFg7XG4gICAgICB2YXIgcG9wdXBSaWdodCA9IHBvcHVwTGVmdCArIHBvcHVwV2lkdGg7XG4gICAgICB2YXIgcG9wdXBUb3AgPSBwb3B1cFJlY3QueSArIG5leHRPZmZzZXRZO1xuICAgICAgdmFyIHBvcHVwQm90dG9tID0gcG9wdXBUb3AgKyBwb3B1cEhlaWdodDtcbiAgICAgIHZhciB0YXJnZXRMZWZ0ID0gdGFyZ2V0UmVjdC54O1xuICAgICAgdmFyIHRhcmdldFJpZ2h0ID0gdGFyZ2V0TGVmdCArIHRhcmdldFdpZHRoO1xuICAgICAgdmFyIHRhcmdldFRvcCA9IHRhcmdldFJlY3QueTtcbiAgICAgIHZhciB0YXJnZXRCb3R0b20gPSB0YXJnZXRUb3AgKyB0YXJnZXRIZWlnaHQ7XG4gICAgICB2YXIgbWF4TGVmdCA9IE1hdGgubWF4KHBvcHVwTGVmdCwgdGFyZ2V0TGVmdCk7XG4gICAgICB2YXIgbWluUmlnaHQgPSBNYXRoLm1pbihwb3B1cFJpZ2h0LCB0YXJnZXRSaWdodCk7XG4gICAgICB2YXIgeENlbnRlciA9IChtYXhMZWZ0ICsgbWluUmlnaHQpIC8gMjtcbiAgICAgIHZhciBuZXh0QXJyb3dYID0geENlbnRlciAtIHBvcHVwTGVmdDtcbiAgICAgIHZhciBtYXhUb3AgPSBNYXRoLm1heChwb3B1cFRvcCwgdGFyZ2V0VG9wKTtcbiAgICAgIHZhciBtaW5Cb3R0b20gPSBNYXRoLm1pbihwb3B1cEJvdHRvbSwgdGFyZ2V0Qm90dG9tKTtcbiAgICAgIHZhciB5Q2VudGVyID0gKG1heFRvcCArIG1pbkJvdHRvbSkgLyAyO1xuICAgICAgdmFyIG5leHRBcnJvd1kgPSB5Q2VudGVyIC0gcG9wdXBUb3A7XG4gICAgICBvblBvcHVwQWxpZ24gPT09IG51bGwgfHwgb25Qb3B1cEFsaWduID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvblBvcHVwQWxpZ24ocG9wdXBFbGUsIG5leHRBbGlnbkluZm8pO1xuICAgICAgc2V0T2Zmc2V0SW5mbyh7XG4gICAgICAgIHJlYWR5OiB0cnVlLFxuICAgICAgICBvZmZzZXRYOiBuZXh0T2Zmc2V0WCAvIF9zY2FsZVgsXG4gICAgICAgIG9mZnNldFk6IG5leHRPZmZzZXRZIC8gX3NjYWxlWSxcbiAgICAgICAgYXJyb3dYOiBuZXh0QXJyb3dYIC8gX3NjYWxlWCxcbiAgICAgICAgYXJyb3dZOiBuZXh0QXJyb3dZIC8gX3NjYWxlWSxcbiAgICAgICAgc2NhbGVYOiBfc2NhbGVYLFxuICAgICAgICBzY2FsZVk6IF9zY2FsZVksXG4gICAgICAgIGFsaWduOiBuZXh0QWxpZ25JbmZvXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuICB2YXIgdHJpZ2dlckFsaWduID0gZnVuY3Rpb24gdHJpZ2dlckFsaWduKCkge1xuICAgIGFsaWduQ291bnRSZWYuY3VycmVudCArPSAxO1xuICAgIHZhciBpZCA9IGFsaWduQ291bnRSZWYuY3VycmVudDtcblxuICAgIC8vIE1lcmdlIGFsbCBhbGlnbiByZXF1aXJlbWVudCBpbnRvIG9uZSBmcmFtZVxuICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGFsaWduQ291bnRSZWYuY3VycmVudCA9PT0gaWQpIHtcbiAgICAgICAgb25BbGlnbigpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vIFJlc2V0IHJlYWR5IHN0YXR1cyB3aGVuIHBsYWNlbWVudCAmIG9wZW4gY2hhbmdlZFxuICB2YXIgcmVzZXRSZWFkeSA9IGZ1bmN0aW9uIHJlc2V0UmVhZHkoKSB7XG4gICAgc2V0T2Zmc2V0SW5mbyhmdW5jdGlvbiAob3JpKSB7XG4gICAgICByZXR1cm4gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBvcmkpLCB7fSwge1xuICAgICAgICByZWFkeTogZmFsc2VcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuICB1c2VMYXlvdXRFZmZlY3QocmVzZXRSZWFkeSwgW3BsYWNlbWVudF0pO1xuICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmICghb3Blbikge1xuICAgICAgcmVzZXRSZWFkeSgpO1xuICAgIH1cbiAgfSwgW29wZW5dKTtcbiAgcmV0dXJuIFtvZmZzZXRJbmZvLnJlYWR5LCBvZmZzZXRJbmZvLm9mZnNldFgsIG9mZnNldEluZm8ub2Zmc2V0WSwgb2Zmc2V0SW5mby5hcnJvd1gsIG9mZnNldEluZm8uYXJyb3dZLCBvZmZzZXRJbmZvLnNjYWxlWCwgb2Zmc2V0SW5mby5zY2FsZVksIG9mZnNldEluZm8uYWxpZ24sIHRyaWdnZXJBbGlnbl07XG59IiwiaW1wb3J0IF90b0NvbnN1bWFibGVBcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdG9Db25zdW1hYmxlQXJyYXlcIjtcbmltcG9ydCB1c2VMYXlvdXRFZmZlY3QgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlTGF5b3V0RWZmZWN0XCI7XG5pbXBvcnQgeyBjb2xsZWN0U2Nyb2xsZXIsIGdldFdpbiB9IGZyb20gXCIuLi91dGlsXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VXYXRjaChvcGVuLCB0YXJnZXQsIHBvcHVwLCBvbkFsaWduKSB7XG4gIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKG9wZW4gJiYgdGFyZ2V0ICYmIHBvcHVwKSB7XG4gICAgICB2YXIgdGFyZ2V0RWxlbWVudCA9IHRhcmdldDtcbiAgICAgIHZhciBwb3B1cEVsZW1lbnQgPSBwb3B1cDtcbiAgICAgIHZhciB0YXJnZXRTY3JvbGxMaXN0ID0gY29sbGVjdFNjcm9sbGVyKHRhcmdldEVsZW1lbnQpO1xuICAgICAgdmFyIHBvcHVwU2Nyb2xsTGlzdCA9IGNvbGxlY3RTY3JvbGxlcihwb3B1cEVsZW1lbnQpO1xuICAgICAgdmFyIHdpbiA9IGdldFdpbihwb3B1cEVsZW1lbnQpO1xuICAgICAgdmFyIG1lcmdlZExpc3QgPSBuZXcgU2V0KFt3aW5dLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkodGFyZ2V0U2Nyb2xsTGlzdCksIF90b0NvbnN1bWFibGVBcnJheShwb3B1cFNjcm9sbExpc3QpKSk7XG4gICAgICBmdW5jdGlvbiBub3RpZnlTY3JvbGwoKSB7XG4gICAgICAgIG9uQWxpZ24oKTtcbiAgICAgIH1cbiAgICAgIG1lcmdlZExpc3QuZm9yRWFjaChmdW5jdGlvbiAoc2Nyb2xsZXIpIHtcbiAgICAgICAgc2Nyb2xsZXIuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgbm90aWZ5U2Nyb2xsLCB7XG4gICAgICAgICAgcGFzc2l2ZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgd2luLmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG5vdGlmeVNjcm9sbCwge1xuICAgICAgICBwYXNzaXZlOiB0cnVlXG4gICAgICB9KTtcblxuICAgICAgLy8gRmlyc3QgdGltZSBhbHdheXMgZG8gYWxpZ25cbiAgICAgIG9uQWxpZ24oKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIG1lcmdlZExpc3QuZm9yRWFjaChmdW5jdGlvbiAoc2Nyb2xsZXIpIHtcbiAgICAgICAgICBzY3JvbGxlci5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBub3RpZnlTY3JvbGwpO1xuICAgICAgICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBub3RpZnlTY3JvbGwpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfVxuICB9LCBbb3BlbiwgdGFyZ2V0LCBwb3B1cF0pO1xufSIsImltcG9ydCBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzXCI7XG52YXIgX2V4Y2x1ZGVkID0gW1wiY2hpbGRyZW5cIl07XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgdmFyIENvbnRleHQgPSAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlQ29udGV4dCh7fSk7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3Rpb25Qcm92aWRlcihfcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IF9yZWYuY2hpbGRyZW4sXG4gICAgcHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoX3JlZiwgX2V4Y2x1ZGVkKTtcbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KENvbnRleHQuUHJvdmlkZXIsIHtcbiAgICB2YWx1ZTogcHJvcHNcbiAgfSwgY2hpbGRyZW4pO1xufSIsImltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfY3JlYXRlU3VwZXIgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZVN1cGVyXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG52YXIgRG9tV3JhcHBlciA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICBfaW5oZXJpdHMoRG9tV3JhcHBlciwgX1JlYWN0JENvbXBvbmVudCk7XG4gIHZhciBfc3VwZXIgPSBfY3JlYXRlU3VwZXIoRG9tV3JhcHBlcik7XG4gIGZ1bmN0aW9uIERvbVdyYXBwZXIoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIERvbVdyYXBwZXIpO1xuICAgIHJldHVybiBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuICBfY3JlYXRlQ2xhc3MoRG9tV3JhcHBlciwgW3tcbiAgICBrZXk6IFwicmVuZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLmNoaWxkcmVuO1xuICAgIH1cbiAgfV0pO1xuICByZXR1cm4gRG9tV3JhcHBlcjtcbn0oUmVhY3QuQ29tcG9uZW50KTtcbmV4cG9ydCBkZWZhdWx0IERvbVdyYXBwZXI7IiwiZXhwb3J0IHZhciBTVEFUVVNfTk9ORSA9ICdub25lJztcbmV4cG9ydCB2YXIgU1RBVFVTX0FQUEVBUiA9ICdhcHBlYXInO1xuZXhwb3J0IHZhciBTVEFUVVNfRU5URVIgPSAnZW50ZXInO1xuZXhwb3J0IHZhciBTVEFUVVNfTEVBVkUgPSAnbGVhdmUnO1xuZXhwb3J0IHZhciBTVEVQX05PTkUgPSAnbm9uZSc7XG5leHBvcnQgdmFyIFNURVBfUFJFUEFSRSA9ICdwcmVwYXJlJztcbmV4cG9ydCB2YXIgU1RFUF9TVEFSVCA9ICdzdGFydCc7XG5leHBvcnQgdmFyIFNURVBfQUNUSVZFID0gJ2FjdGl2ZSc7XG5leHBvcnQgdmFyIFNURVBfQUNUSVZBVEVEID0gJ2VuZCc7XG4vKipcbiAqIFVzZWQgZm9yIGRpc2FibGVkIG1vdGlvbiBjYXNlLlxuICogUHJlcGFyZSBzdGFnZSB3aWxsIHN0aWxsIHdvcmsgYnV0IHN0YXJ0ICYgYWN0aXZlIHdpbGwgYmUgc2tpcHBlZC5cbiAqL1xuZXhwb3J0IHZhciBTVEVQX1BSRVBBUkVEID0gJ3ByZXBhcmVkJzsiLCJpbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mXCI7XG5pbXBvcnQgY2FuVXNlRE9NIGZyb20gXCJyYy11dGlsL2VzL0RvbS9jYW5Vc2VEb21cIjtcbi8vID09PT09PT09PT09PT09PT09IFRyYW5zaXRpb24gPT09PT09PT09PT09PT09PT1cbi8vIEV2ZW50IHdyYXBwZXIuIENvcHkgZnJvbSByZWFjdCBzb3VyY2UgY29kZVxuZnVuY3Rpb24gbWFrZVByZWZpeE1hcChzdHlsZVByb3AsIGV2ZW50TmFtZSkge1xuICB2YXIgcHJlZml4ZXMgPSB7fTtcbiAgcHJlZml4ZXNbc3R5bGVQcm9wLnRvTG93ZXJDYXNlKCldID0gZXZlbnROYW1lLnRvTG93ZXJDYXNlKCk7XG4gIHByZWZpeGVzW1wiV2Via2l0XCIuY29uY2F0KHN0eWxlUHJvcCldID0gXCJ3ZWJraXRcIi5jb25jYXQoZXZlbnROYW1lKTtcbiAgcHJlZml4ZXNbXCJNb3pcIi5jb25jYXQoc3R5bGVQcm9wKV0gPSBcIm1velwiLmNvbmNhdChldmVudE5hbWUpO1xuICBwcmVmaXhlc1tcIm1zXCIuY29uY2F0KHN0eWxlUHJvcCldID0gXCJNU1wiLmNvbmNhdChldmVudE5hbWUpO1xuICBwcmVmaXhlc1tcIk9cIi5jb25jYXQoc3R5bGVQcm9wKV0gPSBcIm9cIi5jb25jYXQoZXZlbnROYW1lLnRvTG93ZXJDYXNlKCkpO1xuICByZXR1cm4gcHJlZml4ZXM7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVuZG9yUHJlZml4ZXMoZG9tU3VwcG9ydCwgd2luKSB7XG4gIHZhciBwcmVmaXhlcyA9IHtcbiAgICBhbmltYXRpb25lbmQ6IG1ha2VQcmVmaXhNYXAoJ0FuaW1hdGlvbicsICdBbmltYXRpb25FbmQnKSxcbiAgICB0cmFuc2l0aW9uZW5kOiBtYWtlUHJlZml4TWFwKCdUcmFuc2l0aW9uJywgJ1RyYW5zaXRpb25FbmQnKVxuICB9O1xuICBpZiAoZG9tU3VwcG9ydCkge1xuICAgIGlmICghKCdBbmltYXRpb25FdmVudCcgaW4gd2luKSkge1xuICAgICAgZGVsZXRlIHByZWZpeGVzLmFuaW1hdGlvbmVuZC5hbmltYXRpb247XG4gICAgfVxuICAgIGlmICghKCdUcmFuc2l0aW9uRXZlbnQnIGluIHdpbikpIHtcbiAgICAgIGRlbGV0ZSBwcmVmaXhlcy50cmFuc2l0aW9uZW5kLnRyYW5zaXRpb247XG4gICAgfVxuICB9XG4gIHJldHVybiBwcmVmaXhlcztcbn1cbnZhciB2ZW5kb3JQcmVmaXhlcyA9IGdldFZlbmRvclByZWZpeGVzKGNhblVzZURPTSgpLCB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHt9KTtcbnZhciBzdHlsZSA9IHt9O1xuaWYgKGNhblVzZURPTSgpKSB7XG4gIHZhciBfZG9jdW1lbnQkY3JlYXRlRWxlbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgc3R5bGUgPSBfZG9jdW1lbnQkY3JlYXRlRWxlbWUuc3R5bGU7XG59XG52YXIgcHJlZml4ZWRFdmVudE5hbWVzID0ge307XG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoZXZlbnROYW1lKSB7XG4gIGlmIChwcmVmaXhlZEV2ZW50TmFtZXNbZXZlbnROYW1lXSkge1xuICAgIHJldHVybiBwcmVmaXhlZEV2ZW50TmFtZXNbZXZlbnROYW1lXTtcbiAgfVxuICB2YXIgcHJlZml4TWFwID0gdmVuZG9yUHJlZml4ZXNbZXZlbnROYW1lXTtcbiAgaWYgKHByZWZpeE1hcCkge1xuICAgIHZhciBzdHlsZVByb3BMaXN0ID0gT2JqZWN0LmtleXMocHJlZml4TWFwKTtcbiAgICB2YXIgbGVuID0gc3R5bGVQcm9wTGlzdC5sZW5ndGg7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgdmFyIHN0eWxlUHJvcCA9IHN0eWxlUHJvcExpc3RbaV07XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHByZWZpeE1hcCwgc3R5bGVQcm9wKSAmJiBzdHlsZVByb3AgaW4gc3R5bGUpIHtcbiAgICAgICAgcHJlZml4ZWRFdmVudE5hbWVzW2V2ZW50TmFtZV0gPSBwcmVmaXhNYXBbc3R5bGVQcm9wXTtcbiAgICAgICAgcmV0dXJuIHByZWZpeGVkRXZlbnROYW1lc1tldmVudE5hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG52YXIgaW50ZXJuYWxBbmltYXRpb25FbmROYW1lID0gZ2V0VmVuZG9yUHJlZml4ZWRFdmVudE5hbWUoJ2FuaW1hdGlvbmVuZCcpO1xudmFyIGludGVybmFsVHJhbnNpdGlvbkVuZE5hbWUgPSBnZXRWZW5kb3JQcmVmaXhlZEV2ZW50TmFtZSgndHJhbnNpdGlvbmVuZCcpO1xuZXhwb3J0IHZhciBzdXBwb3J0VHJhbnNpdGlvbiA9ICEhKGludGVybmFsQW5pbWF0aW9uRW5kTmFtZSAmJiBpbnRlcm5hbFRyYW5zaXRpb25FbmROYW1lKTtcbmV4cG9ydCB2YXIgYW5pbWF0aW9uRW5kTmFtZSA9IGludGVybmFsQW5pbWF0aW9uRW5kTmFtZSB8fCAnYW5pbWF0aW9uZW5kJztcbmV4cG9ydCB2YXIgdHJhbnNpdGlvbkVuZE5hbWUgPSBpbnRlcm5hbFRyYW5zaXRpb25FbmROYW1lIHx8ICd0cmFuc2l0aW9uZW5kJztcbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2l0aW9uTmFtZSh0cmFuc2l0aW9uTmFtZSwgdHJhbnNpdGlvblR5cGUpIHtcbiAgaWYgKCF0cmFuc2l0aW9uTmFtZSkgcmV0dXJuIG51bGw7XG4gIGlmIChfdHlwZW9mKHRyYW5zaXRpb25OYW1lKSA9PT0gJ29iamVjdCcpIHtcbiAgICB2YXIgdHlwZSA9IHRyYW5zaXRpb25UeXBlLnJlcGxhY2UoLy1cXHcvZywgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICByZXR1cm4gbWF0Y2hbMV0udG9VcHBlckNhc2UoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gdHJhbnNpdGlvbk5hbWVbdHlwZV07XG4gIH1cbiAgcmV0dXJuIFwiXCIuY29uY2F0KHRyYW5zaXRpb25OYW1lLCBcIi1cIikuY29uY2F0KHRyYW5zaXRpb25UeXBlKTtcbn0iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBhbmltYXRpb25FbmROYW1lLCB0cmFuc2l0aW9uRW5kTmFtZSB9IGZyb20gXCIuLi91dGlsL21vdGlvblwiO1xuZXhwb3J0IGRlZmF1bHQgKGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB2YXIgY2FjaGVFbGVtZW50UmVmID0gdXNlUmVmKCk7XG5cbiAgLy8gQ2FjaGUgY2FsbGJhY2tcbiAgdmFyIGNhbGxiYWNrUmVmID0gdXNlUmVmKGNhbGxiYWNrKTtcbiAgY2FsbGJhY2tSZWYuY3VycmVudCA9IGNhbGxiYWNrO1xuXG4gIC8vIEludGVybmFsIG1vdGlvbiBldmVudCBoYW5kbGVyXG4gIHZhciBvbkludGVybmFsTW90aW9uRW5kID0gUmVhY3QudXNlQ2FsbGJhY2soZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgY2FsbGJhY2tSZWYuY3VycmVudChldmVudCk7XG4gIH0sIFtdKTtcblxuICAvLyBSZW1vdmUgZXZlbnRzXG4gIGZ1bmN0aW9uIHJlbW92ZU1vdGlvbkV2ZW50cyhlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmFuc2l0aW9uRW5kTmFtZSwgb25JbnRlcm5hbE1vdGlvbkVuZCk7XG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoYW5pbWF0aW9uRW5kTmFtZSwgb25JbnRlcm5hbE1vdGlvbkVuZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUGF0Y2ggZXZlbnRzXG4gIGZ1bmN0aW9uIHBhdGNoTW90aW9uRXZlbnRzKGVsZW1lbnQpIHtcbiAgICBpZiAoY2FjaGVFbGVtZW50UmVmLmN1cnJlbnQgJiYgY2FjaGVFbGVtZW50UmVmLmN1cnJlbnQgIT09IGVsZW1lbnQpIHtcbiAgICAgIHJlbW92ZU1vdGlvbkV2ZW50cyhjYWNoZUVsZW1lbnRSZWYuY3VycmVudCk7XG4gICAgfVxuICAgIGlmIChlbGVtZW50ICYmIGVsZW1lbnQgIT09IGNhY2hlRWxlbWVudFJlZi5jdXJyZW50KSB7XG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJhbnNpdGlvbkVuZE5hbWUsIG9uSW50ZXJuYWxNb3Rpb25FbmQpO1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGFuaW1hdGlvbkVuZE5hbWUsIG9uSW50ZXJuYWxNb3Rpb25FbmQpO1xuXG4gICAgICAvLyBTYXZlIGFzIGNhY2hlIGluIGNhc2UgZG9tIHJlbW92ZWQgdHJpZ2dlciBieSBgbW90aW9uRGVhZGxpbmVgXG4gICAgICBjYWNoZUVsZW1lbnRSZWYuY3VycmVudCA9IGVsZW1lbnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2xlYW4gdXAgd2hlbiByZW1vdmVkXG4gIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJlbW92ZU1vdGlvbkV2ZW50cyhjYWNoZUVsZW1lbnRSZWYuY3VycmVudCk7XG4gICAgfTtcbiAgfSwgW10pO1xuICByZXR1cm4gW3BhdGNoTW90aW9uRXZlbnRzLCByZW1vdmVNb3Rpb25FdmVudHNdO1xufSk7IiwiaW1wb3J0IHsgdXNlRWZmZWN0LCB1c2VMYXlvdXRFZmZlY3QgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgY2FuVXNlRG9tIGZyb20gXCJyYy11dGlsL2VzL0RvbS9jYW5Vc2VEb21cIjtcblxuLy8gSXQncyBzYWZlIHRvIHVzZSBgdXNlTGF5b3V0RWZmZWN0YCBidXQgdGhlIHdhcm5pbmcgaXMgYW5ub3lpbmdcbnZhciB1c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0ID0gY2FuVXNlRG9tKCkgPyB1c2VMYXlvdXRFZmZlY3QgOiB1c2VFZmZlY3Q7XG5leHBvcnQgZGVmYXVsdCB1c2VJc29tb3JwaGljTGF5b3V0RWZmZWN0OyIsInZhciByYWYgPSBmdW5jdGlvbiByYWYoY2FsbGJhY2spIHtcbiAgcmV0dXJuICtzZXRUaW1lb3V0KGNhbGxiYWNrLCAxNik7XG59O1xudmFyIGNhZiA9IGZ1bmN0aW9uIGNhZihudW0pIHtcbiAgcmV0dXJuIGNsZWFyVGltZW91dChudW0pO1xufTtcbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiAncmVxdWVzdEFuaW1hdGlvbkZyYW1lJyBpbiB3aW5kb3cpIHtcbiAgcmFmID0gZnVuY3Rpb24gcmFmKGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2FsbGJhY2spO1xuICB9O1xuICBjYWYgPSBmdW5jdGlvbiBjYWYoaGFuZGxlKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZShoYW5kbGUpO1xuICB9O1xufVxudmFyIHJhZlVVSUQgPSAwO1xudmFyIHJhZklkcyA9IG5ldyBNYXAoKTtcbmZ1bmN0aW9uIGNsZWFudXAoaWQpIHtcbiAgcmFmSWRzLmRlbGV0ZShpZCk7XG59XG52YXIgd3JhcHBlclJhZiA9IGZ1bmN0aW9uIHdyYXBwZXJSYWYoY2FsbGJhY2spIHtcbiAgdmFyIHRpbWVzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiAxO1xuICByYWZVVUlEICs9IDE7XG4gIHZhciBpZCA9IHJhZlVVSUQ7XG4gIGZ1bmN0aW9uIGNhbGxSZWYobGVmdFRpbWVzKSB7XG4gICAgaWYgKGxlZnRUaW1lcyA9PT0gMCkge1xuICAgICAgLy8gQ2xlYW4gdXBcbiAgICAgIGNsZWFudXAoaWQpO1xuXG4gICAgICAvLyBUcmlnZ2VyXG4gICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBOZXh0IHJhZlxuICAgICAgdmFyIHJlYWxJZCA9IHJhZihmdW5jdGlvbiAoKSB7XG4gICAgICAgIGNhbGxSZWYobGVmdFRpbWVzIC0gMSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gQmluZCByZWFsIHJhZiBpZFxuICAgICAgcmFmSWRzLnNldChpZCwgcmVhbElkKTtcbiAgICB9XG4gIH1cbiAgY2FsbFJlZih0aW1lcyk7XG4gIHJldHVybiBpZDtcbn07XG53cmFwcGVyUmFmLmNhbmNlbCA9IGZ1bmN0aW9uIChpZCkge1xuICB2YXIgcmVhbElkID0gcmFmSWRzLmdldChpZCk7XG4gIGNsZWFudXAocmVhbElkKTtcbiAgcmV0dXJuIGNhZihyZWFsSWQpO1xufTtcbmV4cG9ydCBkZWZhdWx0IHdyYXBwZXJSYWY7IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHJhZiBmcm9tIFwicmMtdXRpbC9lcy9yYWZcIjtcbmV4cG9ydCBkZWZhdWx0IChmdW5jdGlvbiAoKSB7XG4gIHZhciBuZXh0RnJhbWVSZWYgPSBSZWFjdC51c2VSZWYobnVsbCk7XG4gIGZ1bmN0aW9uIGNhbmNlbE5leHRGcmFtZSgpIHtcbiAgICByYWYuY2FuY2VsKG5leHRGcmFtZVJlZi5jdXJyZW50KTtcbiAgfVxuICBmdW5jdGlvbiBuZXh0RnJhbWUoY2FsbGJhY2spIHtcbiAgICB2YXIgZGVsYXkgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDI7XG4gICAgY2FuY2VsTmV4dEZyYW1lKCk7XG4gICAgdmFyIG5leHRGcmFtZUlkID0gcmFmKGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChkZWxheSA8PSAxKSB7XG4gICAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgICBpc0NhbmNlbGVkOiBmdW5jdGlvbiBpc0NhbmNlbGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5leHRGcmFtZUlkICE9PSBuZXh0RnJhbWVSZWYuY3VycmVudDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV4dEZyYW1lKGNhbGxiYWNrLCBkZWxheSAtIDEpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG5leHRGcmFtZVJlZi5jdXJyZW50ID0gbmV4dEZyYW1lSWQ7XG4gIH1cbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgY2FuY2VsTmV4dEZyYW1lKCk7XG4gICAgfTtcbiAgfSwgW10pO1xuICByZXR1cm4gW25leHRGcmFtZSwgY2FuY2VsTmV4dEZyYW1lXTtcbn0pOyIsImltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IHVzZVN0YXRlIGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZVN0YXRlXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBTVEVQX0FDVElWQVRFRCwgU1RFUF9BQ1RJVkUsIFNURVBfTk9ORSwgU1RFUF9QUkVQQVJFLCBTVEVQX1BSRVBBUkVELCBTVEVQX1NUQVJUIH0gZnJvbSBcIi4uL2ludGVyZmFjZVwiO1xuaW1wb3J0IHVzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3QgZnJvbSBcIi4vdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdFwiO1xuaW1wb3J0IHVzZU5leHRGcmFtZSBmcm9tIFwiLi91c2VOZXh0RnJhbWVcIjtcbnZhciBGVUxMX1NURVBfUVVFVUUgPSBbU1RFUF9QUkVQQVJFLCBTVEVQX1NUQVJULCBTVEVQX0FDVElWRSwgU1RFUF9BQ1RJVkFURURdO1xudmFyIFNJTVBMRV9TVEVQX1FVRVVFID0gW1NURVBfUFJFUEFSRSwgU1RFUF9QUkVQQVJFRF07XG5cbi8qKiBTa2lwIGN1cnJlbnQgc3RlcCAqL1xuZXhwb3J0IHZhciBTa2lwU3RlcCA9IGZhbHNlO1xuLyoqIEN1cnJlbnQgc3RlcCBzaG91bGQgYmUgdXBkYXRlIGluICovXG5leHBvcnQgdmFyIERvU3RlcCA9IHRydWU7XG5leHBvcnQgZnVuY3Rpb24gaXNBY3RpdmUoc3RlcCkge1xuICByZXR1cm4gc3RlcCA9PT0gU1RFUF9BQ1RJVkUgfHwgc3RlcCA9PT0gU1RFUF9BQ1RJVkFURUQ7XG59XG5leHBvcnQgZGVmYXVsdCAoZnVuY3Rpb24gKHN0YXR1cywgcHJlcGFyZU9ubHksIGNhbGxiYWNrKSB7XG4gIHZhciBfdXNlU3RhdGUgPSB1c2VTdGF0ZShTVEVQX05PTkUpLFxuICAgIF91c2VTdGF0ZTIgPSBfc2xpY2VkVG9BcnJheShfdXNlU3RhdGUsIDIpLFxuICAgIHN0ZXAgPSBfdXNlU3RhdGUyWzBdLFxuICAgIHNldFN0ZXAgPSBfdXNlU3RhdGUyWzFdO1xuICB2YXIgX3VzZU5leHRGcmFtZSA9IHVzZU5leHRGcmFtZSgpLFxuICAgIF91c2VOZXh0RnJhbWUyID0gX3NsaWNlZFRvQXJyYXkoX3VzZU5leHRGcmFtZSwgMiksXG4gICAgbmV4dEZyYW1lID0gX3VzZU5leHRGcmFtZTJbMF0sXG4gICAgY2FuY2VsTmV4dEZyYW1lID0gX3VzZU5leHRGcmFtZTJbMV07XG4gIGZ1bmN0aW9uIHN0YXJ0UXVldWUoKSB7XG4gICAgc2V0U3RlcChTVEVQX1BSRVBBUkUsIHRydWUpO1xuICB9XG4gIHZhciBTVEVQX1FVRVVFID0gcHJlcGFyZU9ubHkgPyBTSU1QTEVfU1RFUF9RVUVVRSA6IEZVTExfU1RFUF9RVUVVRTtcbiAgdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHN0ZXAgIT09IFNURVBfTk9ORSAmJiBzdGVwICE9PSBTVEVQX0FDVElWQVRFRCkge1xuICAgICAgdmFyIGluZGV4ID0gU1RFUF9RVUVVRS5pbmRleE9mKHN0ZXApO1xuICAgICAgdmFyIG5leHRTdGVwID0gU1RFUF9RVUVVRVtpbmRleCArIDFdO1xuICAgICAgdmFyIHJlc3VsdCA9IGNhbGxiYWNrKHN0ZXApO1xuICAgICAgaWYgKHJlc3VsdCA9PT0gU2tpcFN0ZXApIHtcbiAgICAgICAgLy8gU2tpcCB3aGVuIG5vIG5lZWRlZFxuICAgICAgICBzZXRTdGVwKG5leHRTdGVwLCB0cnVlKTtcbiAgICAgIH0gZWxzZSBpZiAobmV4dFN0ZXApIHtcbiAgICAgICAgLy8gRG8gYXMgZnJhbWUgZm9yIHN0ZXAgdXBkYXRlXG4gICAgICAgIG5leHRGcmFtZShmdW5jdGlvbiAoaW5mbykge1xuICAgICAgICAgIGZ1bmN0aW9uIGRvTmV4dCgpIHtcbiAgICAgICAgICAgIC8vIFNraXAgc2luY2UgY3VycmVudCBxdWV1ZSBpcyBvb2RcbiAgICAgICAgICAgIGlmIChpbmZvLmlzQ2FuY2VsZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgc2V0U3RlcChuZXh0U3RlcCwgdHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXN1bHQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGRvTmV4dCgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBPbmx5IHByb21pc2Ugc2hvdWxkIGJlIGFzeW5jXG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUocmVzdWx0KS50aGVuKGRvTmV4dCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtzdGF0dXMsIHN0ZXBdKTtcbiAgUmVhY3QudXNlRWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgY2FuY2VsTmV4dEZyYW1lKCk7XG4gICAgfTtcbiAgfSwgW10pO1xuICByZXR1cm4gW3N0YXJ0UXVldWUsIHN0ZXBdO1xufSk7IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCB1c2VTdGF0ZSBmcm9tIFwicmMtdXRpbC9lcy9ob29rcy91c2VTdGF0ZVwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBTVEFUVVNfQVBQRUFSLCBTVEFUVVNfRU5URVIsIFNUQVRVU19MRUFWRSwgU1RBVFVTX05PTkUsIFNURVBfQUNUSVZFLCBTVEVQX1BSRVBBUkUsIFNURVBfUFJFUEFSRUQsIFNURVBfU1RBUlQgfSBmcm9tIFwiLi4vaW50ZXJmYWNlXCI7XG5pbXBvcnQgdXNlRG9tTW90aW9uRXZlbnRzIGZyb20gXCIuL3VzZURvbU1vdGlvbkV2ZW50c1wiO1xuaW1wb3J0IHVzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3QgZnJvbSBcIi4vdXNlSXNvbW9ycGhpY0xheW91dEVmZmVjdFwiO1xuaW1wb3J0IHVzZVN0ZXBRdWV1ZSwgeyBEb1N0ZXAsIGlzQWN0aXZlLCBTa2lwU3RlcCB9IGZyb20gXCIuL3VzZVN0ZXBRdWV1ZVwiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdXNlU3RhdHVzKHN1cHBvcnRNb3Rpb24sIHZpc2libGUsIGdldEVsZW1lbnQsIF9yZWYpIHtcbiAgdmFyIF9yZWYkbW90aW9uRW50ZXIgPSBfcmVmLm1vdGlvbkVudGVyLFxuICAgIG1vdGlvbkVudGVyID0gX3JlZiRtb3Rpb25FbnRlciA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9yZWYkbW90aW9uRW50ZXIsXG4gICAgX3JlZiRtb3Rpb25BcHBlYXIgPSBfcmVmLm1vdGlvbkFwcGVhcixcbiAgICBtb3Rpb25BcHBlYXIgPSBfcmVmJG1vdGlvbkFwcGVhciA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9yZWYkbW90aW9uQXBwZWFyLFxuICAgIF9yZWYkbW90aW9uTGVhdmUgPSBfcmVmLm1vdGlvbkxlYXZlLFxuICAgIG1vdGlvbkxlYXZlID0gX3JlZiRtb3Rpb25MZWF2ZSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9yZWYkbW90aW9uTGVhdmUsXG4gICAgbW90aW9uRGVhZGxpbmUgPSBfcmVmLm1vdGlvbkRlYWRsaW5lLFxuICAgIG1vdGlvbkxlYXZlSW1tZWRpYXRlbHkgPSBfcmVmLm1vdGlvbkxlYXZlSW1tZWRpYXRlbHksXG4gICAgb25BcHBlYXJQcmVwYXJlID0gX3JlZi5vbkFwcGVhclByZXBhcmUsXG4gICAgb25FbnRlclByZXBhcmUgPSBfcmVmLm9uRW50ZXJQcmVwYXJlLFxuICAgIG9uTGVhdmVQcmVwYXJlID0gX3JlZi5vbkxlYXZlUHJlcGFyZSxcbiAgICBvbkFwcGVhclN0YXJ0ID0gX3JlZi5vbkFwcGVhclN0YXJ0LFxuICAgIG9uRW50ZXJTdGFydCA9IF9yZWYub25FbnRlclN0YXJ0LFxuICAgIG9uTGVhdmVTdGFydCA9IF9yZWYub25MZWF2ZVN0YXJ0LFxuICAgIG9uQXBwZWFyQWN0aXZlID0gX3JlZi5vbkFwcGVhckFjdGl2ZSxcbiAgICBvbkVudGVyQWN0aXZlID0gX3JlZi5vbkVudGVyQWN0aXZlLFxuICAgIG9uTGVhdmVBY3RpdmUgPSBfcmVmLm9uTGVhdmVBY3RpdmUsXG4gICAgb25BcHBlYXJFbmQgPSBfcmVmLm9uQXBwZWFyRW5kLFxuICAgIG9uRW50ZXJFbmQgPSBfcmVmLm9uRW50ZXJFbmQsXG4gICAgb25MZWF2ZUVuZCA9IF9yZWYub25MZWF2ZUVuZCxcbiAgICBvblZpc2libGVDaGFuZ2VkID0gX3JlZi5vblZpc2libGVDaGFuZ2VkO1xuICAvLyBVc2VkIGZvciBvdXRlciByZW5kZXIgdXNhZ2UgdG8gYXZvaWQgYHZpc2libGU6IGZhbHNlICYgc3RhdHVzOiBub25lYCB0byByZW5kZXIgbm90aGluZ1xuICB2YXIgX3VzZVN0YXRlID0gdXNlU3RhdGUoKSxcbiAgICBfdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0YXRlLCAyKSxcbiAgICBhc3luY1Zpc2libGUgPSBfdXNlU3RhdGUyWzBdLFxuICAgIHNldEFzeW5jVmlzaWJsZSA9IF91c2VTdGF0ZTJbMV07XG4gIHZhciBfdXNlU3RhdGUzID0gdXNlU3RhdGUoU1RBVFVTX05PTkUpLFxuICAgIF91c2VTdGF0ZTQgPSBfc2xpY2VkVG9BcnJheShfdXNlU3RhdGUzLCAyKSxcbiAgICBzdGF0dXMgPSBfdXNlU3RhdGU0WzBdLFxuICAgIHNldFN0YXR1cyA9IF91c2VTdGF0ZTRbMV07XG4gIHZhciBfdXNlU3RhdGU1ID0gdXNlU3RhdGUobnVsbCksXG4gICAgX3VzZVN0YXRlNiA9IF9zbGljZWRUb0FycmF5KF91c2VTdGF0ZTUsIDIpLFxuICAgIHN0eWxlID0gX3VzZVN0YXRlNlswXSxcbiAgICBzZXRTdHlsZSA9IF91c2VTdGF0ZTZbMV07XG4gIHZhciBtb3VudGVkUmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgdmFyIGRlYWRsaW5lUmVmID0gdXNlUmVmKG51bGwpO1xuXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBEb20gTm9kZSA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgZnVuY3Rpb24gZ2V0RG9tRWxlbWVudCgpIHtcbiAgICByZXR1cm4gZ2V0RWxlbWVudCgpO1xuICB9XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gTW90aW9uIEVuZCA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgYWN0aXZlUmVmID0gdXNlUmVmKGZhbHNlKTtcblxuICAvKipcbiAgICogQ2xlYW4gdXAgc3RhdHVzICYgc3R5bGVcbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZU1vdGlvbkVuZFN0YXR1cygpIHtcbiAgICBzZXRTdGF0dXMoU1RBVFVTX05PTkUsIHRydWUpO1xuICAgIHNldFN0eWxlKG51bGwsIHRydWUpO1xuICB9XG4gIGZ1bmN0aW9uIG9uSW50ZXJuYWxNb3Rpb25FbmQoZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGdldERvbUVsZW1lbnQoKTtcbiAgICBpZiAoZXZlbnQgJiYgIWV2ZW50LmRlYWRsaW5lICYmIGV2ZW50LnRhcmdldCAhPT0gZWxlbWVudCkge1xuICAgICAgLy8gZXZlbnQgZXhpc3RzXG4gICAgICAvLyBub3QgaW5pdGlhdGVkIGJ5IGRlYWRsaW5lXG4gICAgICAvLyB0cmFuc2l0aW9uRW5kIG5vdCBmaXJlZCBieSBpbm5lciBlbGVtZW50c1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgY3VycmVudEFjdGl2ZSA9IGFjdGl2ZVJlZi5jdXJyZW50O1xuICAgIHZhciBjYW5FbmQ7XG4gICAgaWYgKHN0YXR1cyA9PT0gU1RBVFVTX0FQUEVBUiAmJiBjdXJyZW50QWN0aXZlKSB7XG4gICAgICBjYW5FbmQgPSBvbkFwcGVhckVuZCA9PT0gbnVsbCB8fCBvbkFwcGVhckVuZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25BcHBlYXJFbmQoZWxlbWVudCwgZXZlbnQpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSBTVEFUVVNfRU5URVIgJiYgY3VycmVudEFjdGl2ZSkge1xuICAgICAgY2FuRW5kID0gb25FbnRlckVuZCA9PT0gbnVsbCB8fCBvbkVudGVyRW5kID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvbkVudGVyRW5kKGVsZW1lbnQsIGV2ZW50KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gU1RBVFVTX0xFQVZFICYmIGN1cnJlbnRBY3RpdmUpIHtcbiAgICAgIGNhbkVuZCA9IG9uTGVhdmVFbmQgPT09IG51bGwgfHwgb25MZWF2ZUVuZCA9PT0gdm9pZCAwID8gdm9pZCAwIDogb25MZWF2ZUVuZChlbGVtZW50LCBldmVudCk7XG4gICAgfVxuXG4gICAgLy8gT25seSB1cGRhdGUgc3RhdHVzIHdoZW4gYGNhbkVuZGAgYW5kIG5vdCBkZXN0cm95ZWRcbiAgICBpZiAoc3RhdHVzICE9PSBTVEFUVVNfTk9ORSAmJiBjdXJyZW50QWN0aXZlICYmIGNhbkVuZCAhPT0gZmFsc2UpIHtcbiAgICAgIHVwZGF0ZU1vdGlvbkVuZFN0YXR1cygpO1xuICAgIH1cbiAgfVxuICB2YXIgX3VzZURvbU1vdGlvbkV2ZW50cyA9IHVzZURvbU1vdGlvbkV2ZW50cyhvbkludGVybmFsTW90aW9uRW5kKSxcbiAgICBfdXNlRG9tTW90aW9uRXZlbnRzMiA9IF9zbGljZWRUb0FycmF5KF91c2VEb21Nb3Rpb25FdmVudHMsIDEpLFxuICAgIHBhdGNoTW90aW9uRXZlbnRzID0gX3VzZURvbU1vdGlvbkV2ZW50czJbMF07XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gU3RlcCA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgZ2V0RXZlbnRIYW5kbGVycyA9IGZ1bmN0aW9uIGdldEV2ZW50SGFuZGxlcnModGFyZ2V0U3RhdHVzKSB7XG4gICAgdmFyIF9yZWYyLCBfcmVmMywgX3JlZjQ7XG4gICAgc3dpdGNoICh0YXJnZXRTdGF0dXMpIHtcbiAgICAgIGNhc2UgU1RBVFVTX0FQUEVBUjpcbiAgICAgICAgcmV0dXJuIF9yZWYyID0ge30sIF9kZWZpbmVQcm9wZXJ0eShfcmVmMiwgU1RFUF9QUkVQQVJFLCBvbkFwcGVhclByZXBhcmUpLCBfZGVmaW5lUHJvcGVydHkoX3JlZjIsIFNURVBfU1RBUlQsIG9uQXBwZWFyU3RhcnQpLCBfZGVmaW5lUHJvcGVydHkoX3JlZjIsIFNURVBfQUNUSVZFLCBvbkFwcGVhckFjdGl2ZSksIF9yZWYyO1xuICAgICAgY2FzZSBTVEFUVVNfRU5URVI6XG4gICAgICAgIHJldHVybiBfcmVmMyA9IHt9LCBfZGVmaW5lUHJvcGVydHkoX3JlZjMsIFNURVBfUFJFUEFSRSwgb25FbnRlclByZXBhcmUpLCBfZGVmaW5lUHJvcGVydHkoX3JlZjMsIFNURVBfU1RBUlQsIG9uRW50ZXJTdGFydCksIF9kZWZpbmVQcm9wZXJ0eShfcmVmMywgU1RFUF9BQ1RJVkUsIG9uRW50ZXJBY3RpdmUpLCBfcmVmMztcbiAgICAgIGNhc2UgU1RBVFVTX0xFQVZFOlxuICAgICAgICByZXR1cm4gX3JlZjQgPSB7fSwgX2RlZmluZVByb3BlcnR5KF9yZWY0LCBTVEVQX1BSRVBBUkUsIG9uTGVhdmVQcmVwYXJlKSwgX2RlZmluZVByb3BlcnR5KF9yZWY0LCBTVEVQX1NUQVJULCBvbkxlYXZlU3RhcnQpLCBfZGVmaW5lUHJvcGVydHkoX3JlZjQsIFNURVBfQUNUSVZFLCBvbkxlYXZlQWN0aXZlKSwgX3JlZjQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICB9O1xuICB2YXIgZXZlbnRIYW5kbGVycyA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBnZXRFdmVudEhhbmRsZXJzKHN0YXR1cyk7XG4gIH0sIFtzdGF0dXNdKTtcbiAgdmFyIF91c2VTdGVwUXVldWUgPSB1c2VTdGVwUXVldWUoc3RhdHVzLCAhc3VwcG9ydE1vdGlvbiwgZnVuY3Rpb24gKG5ld1N0ZXApIHtcbiAgICAgIC8vIE9ubHkgcHJlcGFyZSBzdGVwIGNhbiBiZSBza2lwXG4gICAgICBpZiAobmV3U3RlcCA9PT0gU1RFUF9QUkVQQVJFKSB7XG4gICAgICAgIHZhciBvblByZXBhcmUgPSBldmVudEhhbmRsZXJzW1NURVBfUFJFUEFSRV07XG4gICAgICAgIGlmICghb25QcmVwYXJlKSB7XG4gICAgICAgICAgcmV0dXJuIFNraXBTdGVwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvblByZXBhcmUoZ2V0RG9tRWxlbWVudCgpKTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVzdCBzdGVwIGlzIHN5bmMgdXBkYXRlXG4gICAgICBpZiAoc3RlcCBpbiBldmVudEhhbmRsZXJzKSB7XG4gICAgICAgIHZhciBfZXZlbnRIYW5kbGVycyRzdGVwO1xuICAgICAgICBzZXRTdHlsZSgoKF9ldmVudEhhbmRsZXJzJHN0ZXAgPSBldmVudEhhbmRsZXJzW3N0ZXBdKSA9PT0gbnVsbCB8fCBfZXZlbnRIYW5kbGVycyRzdGVwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfZXZlbnRIYW5kbGVycyRzdGVwLmNhbGwoZXZlbnRIYW5kbGVycywgZ2V0RG9tRWxlbWVudCgpLCBudWxsKSkgfHwgbnVsbCk7XG4gICAgICB9XG4gICAgICBpZiAoc3RlcCA9PT0gU1RFUF9BQ1RJVkUpIHtcbiAgICAgICAgLy8gUGF0Y2ggZXZlbnRzIHdoZW4gbW90aW9uIG5lZWRlZFxuICAgICAgICBwYXRjaE1vdGlvbkV2ZW50cyhnZXREb21FbGVtZW50KCkpO1xuICAgICAgICBpZiAobW90aW9uRGVhZGxpbmUgPiAwKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGRlYWRsaW5lUmVmLmN1cnJlbnQpO1xuICAgICAgICAgIGRlYWRsaW5lUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIG9uSW50ZXJuYWxNb3Rpb25FbmQoe1xuICAgICAgICAgICAgICBkZWFkbGluZTogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSwgbW90aW9uRGVhZGxpbmUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RlcCA9PT0gU1RFUF9QUkVQQVJFRCkge1xuICAgICAgICB1cGRhdGVNb3Rpb25FbmRTdGF0dXMoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBEb1N0ZXA7XG4gICAgfSksXG4gICAgX3VzZVN0ZXBRdWV1ZTIgPSBfc2xpY2VkVG9BcnJheShfdXNlU3RlcFF1ZXVlLCAyKSxcbiAgICBzdGFydFN0ZXAgPSBfdXNlU3RlcFF1ZXVlMlswXSxcbiAgICBzdGVwID0gX3VzZVN0ZXBRdWV1ZTJbMV07XG4gIHZhciBhY3RpdmUgPSBpc0FjdGl2ZShzdGVwKTtcbiAgYWN0aXZlUmVmLmN1cnJlbnQgPSBhY3RpdmU7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTdGF0dXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBVcGRhdGUgd2l0aCBuZXcgc3RhdHVzXG4gIHVzZUlzb21vcnBoaWNMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHNldEFzeW5jVmlzaWJsZSh2aXNpYmxlKTtcbiAgICB2YXIgaXNNb3VudGVkID0gbW91bnRlZFJlZi5jdXJyZW50O1xuICAgIG1vdW50ZWRSZWYuY3VycmVudCA9IHRydWU7XG5cbiAgICAvLyBpZiAoIXN1cHBvcnRNb3Rpb24pIHtcbiAgICAvLyAgIHJldHVybjtcbiAgICAvLyB9XG5cbiAgICB2YXIgbmV4dFN0YXR1cztcblxuICAgIC8vIEFwcGVhclxuICAgIGlmICghaXNNb3VudGVkICYmIHZpc2libGUgJiYgbW90aW9uQXBwZWFyKSB7XG4gICAgICBuZXh0U3RhdHVzID0gU1RBVFVTX0FQUEVBUjtcbiAgICB9XG5cbiAgICAvLyBFbnRlclxuICAgIGlmIChpc01vdW50ZWQgJiYgdmlzaWJsZSAmJiBtb3Rpb25FbnRlcikge1xuICAgICAgbmV4dFN0YXR1cyA9IFNUQVRVU19FTlRFUjtcbiAgICB9XG5cbiAgICAvLyBMZWF2ZVxuICAgIGlmIChpc01vdW50ZWQgJiYgIXZpc2libGUgJiYgbW90aW9uTGVhdmUgfHwgIWlzTW91bnRlZCAmJiBtb3Rpb25MZWF2ZUltbWVkaWF0ZWx5ICYmICF2aXNpYmxlICYmIG1vdGlvbkxlYXZlKSB7XG4gICAgICBuZXh0U3RhdHVzID0gU1RBVFVTX0xFQVZFO1xuICAgIH1cbiAgICB2YXIgbmV4dEV2ZW50SGFuZGxlcnMgPSBnZXRFdmVudEhhbmRsZXJzKG5leHRTdGF0dXMpO1xuXG4gICAgLy8gVXBkYXRlIHRvIG5leHQgc3RhdHVzXG4gICAgaWYgKG5leHRTdGF0dXMgJiYgKHN1cHBvcnRNb3Rpb24gfHwgbmV4dEV2ZW50SGFuZGxlcnNbU1RFUF9QUkVQQVJFXSkpIHtcbiAgICAgIHNldFN0YXR1cyhuZXh0U3RhdHVzKTtcbiAgICAgIHN0YXJ0U3RlcCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBTZXQgYmFjayBpbiBjYXNlIG5vIG1vdGlvbiBidXQgcHJldiBzdGF0dXMgaGFzIHByZXBhcmUgc3RlcFxuICAgICAgc2V0U3RhdHVzKFNUQVRVU19OT05FKTtcbiAgICB9XG4gIH0sIFt2aXNpYmxlXSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBFZmZlY3QgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBSZXNldCB3aGVuIG1vdGlvbiBjaGFuZ2VkXG4gIHVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKFxuICAgIC8vIENhbmNlbCBhcHBlYXJcbiAgICBzdGF0dXMgPT09IFNUQVRVU19BUFBFQVIgJiYgIW1vdGlvbkFwcGVhciB8fFxuICAgIC8vIENhbmNlbCBlbnRlclxuICAgIHN0YXR1cyA9PT0gU1RBVFVTX0VOVEVSICYmICFtb3Rpb25FbnRlciB8fFxuICAgIC8vIENhbmNlbCBsZWF2ZVxuICAgIHN0YXR1cyA9PT0gU1RBVFVTX0xFQVZFICYmICFtb3Rpb25MZWF2ZSkge1xuICAgICAgc2V0U3RhdHVzKFNUQVRVU19OT05FKTtcbiAgICB9XG4gIH0sIFttb3Rpb25BcHBlYXIsIG1vdGlvbkVudGVyLCBtb3Rpb25MZWF2ZV0pO1xuICB1c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICBtb3VudGVkUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIGNsZWFyVGltZW91dChkZWFkbGluZVJlZi5jdXJyZW50KTtcbiAgICB9O1xuICB9LCBbXSk7XG5cbiAgLy8gVHJpZ2dlciBgb25WaXNpYmxlQ2hhbmdlZGBcbiAgdmFyIGZpcnN0TW91bnRDaGFuZ2VSZWYgPSBSZWFjdC51c2VSZWYoZmFsc2UpO1xuICB1c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIC8vIFt2aXNpYmxlICYgbW90aW9uIG5vdCBlbmRdID0+IFshdmlzaWJsZSAmIG1vdGlvbiBlbmRdIHN0aWxsIG5lZWQgdHJpZ2dlciBvblZpc2libGVDaGFuZ2VkXG4gICAgaWYgKGFzeW5jVmlzaWJsZSkge1xuICAgICAgZmlyc3RNb3VudENoYW5nZVJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGFzeW5jVmlzaWJsZSAhPT0gdW5kZWZpbmVkICYmIHN0YXR1cyA9PT0gU1RBVFVTX05PTkUpIHtcbiAgICAgIC8vIFNraXAgZmlyc3QgcmVuZGVyIGlzIGludmlzaWJsZSBzaW5jZSBpdCdzIG5vdGhpbmcgY2hhbmdlZFxuICAgICAgaWYgKGZpcnN0TW91bnRDaGFuZ2VSZWYuY3VycmVudCB8fCBhc3luY1Zpc2libGUpIHtcbiAgICAgICAgb25WaXNpYmxlQ2hhbmdlZCA9PT0gbnVsbCB8fCBvblZpc2libGVDaGFuZ2VkID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvblZpc2libGVDaGFuZ2VkKGFzeW5jVmlzaWJsZSk7XG4gICAgICB9XG4gICAgICBmaXJzdE1vdW50Q2hhbmdlUmVmLmN1cnJlbnQgPSB0cnVlO1xuICAgIH1cbiAgfSwgW2FzeW5jVmlzaWJsZSwgc3RhdHVzXSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBTdHlsZXMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgbWVyZ2VkU3R5bGUgPSBzdHlsZTtcbiAgaWYgKGV2ZW50SGFuZGxlcnNbU1RFUF9QUkVQQVJFXSAmJiBzdGVwID09PSBTVEVQX1NUQVJUKSB7XG4gICAgbWVyZ2VkU3R5bGUgPSBfb2JqZWN0U3ByZWFkKHtcbiAgICAgIHRyYW5zaXRpb246ICdub25lJ1xuICAgIH0sIG1lcmdlZFN0eWxlKTtcbiAgfVxuICByZXR1cm4gW3N0YXR1cywgc3RlcCwgbWVyZ2VkU3R5bGUsIGFzeW5jVmlzaWJsZSAhPT0gbnVsbCAmJiBhc3luY1Zpc2libGUgIT09IHZvaWQgMCA/IGFzeW5jVmlzaWJsZSA6IHZpc2libGVdO1xufSIsImltcG9ydCBfZGVmaW5lUHJvcGVydHkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2RlZmluZVByb3BlcnR5XCI7XG5pbXBvcnQgX29iamVjdFNwcmVhZCBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0U3ByZWFkMlwiO1xuaW1wb3J0IF9zbGljZWRUb0FycmF5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9zbGljZWRUb0FycmF5XCI7XG5pbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mXCI7XG4vKiBlc2xpbnQtZGlzYWJsZSByZWFjdC9kZWZhdWx0LXByb3BzLW1hdGNoLXByb3AtdHlwZXMsIHJlYWN0L25vLW11bHRpLWNvbXAsIHJlYWN0L3Byb3AtdHlwZXMgKi9cbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IGZpbmRET01Ob2RlIGZyb20gXCJyYy11dGlsL2VzL0RvbS9maW5kRE9NTm9kZVwiO1xuaW1wb3J0IHsgZmlsbFJlZiwgc3VwcG9ydFJlZiB9IGZyb20gXCJyYy11dGlsL2VzL3JlZlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlUmVmIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCBEb21XcmFwcGVyIGZyb20gXCIuL0RvbVdyYXBwZXJcIjtcbmltcG9ydCB1c2VTdGF0dXMgZnJvbSBcIi4vaG9va3MvdXNlU3RhdHVzXCI7XG5pbXBvcnQgeyBpc0FjdGl2ZSB9IGZyb20gXCIuL2hvb2tzL3VzZVN0ZXBRdWV1ZVwiO1xuaW1wb3J0IHsgU1RBVFVTX05PTkUsIFNURVBfUFJFUEFSRSwgU1RFUF9TVEFSVCB9IGZyb20gXCIuL2ludGVyZmFjZVwiO1xuaW1wb3J0IHsgZ2V0VHJhbnNpdGlvbk5hbWUsIHN1cHBvcnRUcmFuc2l0aW9uIH0gZnJvbSBcIi4vdXRpbC9tb3Rpb25cIjtcbi8qKlxuICogYHRyYW5zaXRpb25TdXBwb3J0YCBpcyB1c2VkIGZvciBub25lIHRyYW5zaXRpb24gdGVzdCBjYXNlLlxuICogRGVmYXVsdCB3ZSB1c2UgYnJvd3NlciB0cmFuc2l0aW9uIGV2ZW50IHN1cHBvcnQgY2hlY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5DU1NNb3Rpb24oY29uZmlnKSB7XG4gIHZhciB0cmFuc2l0aW9uU3VwcG9ydCA9IGNvbmZpZztcbiAgaWYgKF90eXBlb2YoY29uZmlnKSA9PT0gJ29iamVjdCcpIHtcbiAgICB0cmFuc2l0aW9uU3VwcG9ydCA9IGNvbmZpZy50cmFuc2l0aW9uU3VwcG9ydDtcbiAgfVxuICBmdW5jdGlvbiBpc1N1cHBvcnRUcmFuc2l0aW9uKHByb3BzLCBjb250ZXh0TW90aW9uKSB7XG4gICAgcmV0dXJuICEhKHByb3BzLm1vdGlvbk5hbWUgJiYgdHJhbnNpdGlvblN1cHBvcnQgJiYgY29udGV4dE1vdGlvbiAhPT0gZmFsc2UpO1xuICB9XG4gIHZhciBDU1NNb3Rpb24gPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICAgIHZhciBfcHJvcHMkdmlzaWJsZSA9IHByb3BzLnZpc2libGUsXG4gICAgICB2aXNpYmxlID0gX3Byb3BzJHZpc2libGUgPT09IHZvaWQgMCA/IHRydWUgOiBfcHJvcHMkdmlzaWJsZSxcbiAgICAgIF9wcm9wcyRyZW1vdmVPbkxlYXZlID0gcHJvcHMucmVtb3ZlT25MZWF2ZSxcbiAgICAgIHJlbW92ZU9uTGVhdmUgPSBfcHJvcHMkcmVtb3ZlT25MZWF2ZSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9wcm9wcyRyZW1vdmVPbkxlYXZlLFxuICAgICAgZm9yY2VSZW5kZXIgPSBwcm9wcy5mb3JjZVJlbmRlcixcbiAgICAgIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgICBtb3Rpb25OYW1lID0gcHJvcHMubW90aW9uTmFtZSxcbiAgICAgIGxlYXZlZENsYXNzTmFtZSA9IHByb3BzLmxlYXZlZENsYXNzTmFtZSxcbiAgICAgIGV2ZW50UHJvcHMgPSBwcm9wcy5ldmVudFByb3BzO1xuICAgIHZhciBfUmVhY3QkdXNlQ29udGV4dCA9IFJlYWN0LnVzZUNvbnRleHQoQ29udGV4dCksXG4gICAgICBjb250ZXh0TW90aW9uID0gX1JlYWN0JHVzZUNvbnRleHQubW90aW9uO1xuICAgIHZhciBzdXBwb3J0TW90aW9uID0gaXNTdXBwb3J0VHJhbnNpdGlvbihwcm9wcywgY29udGV4dE1vdGlvbik7XG5cbiAgICAvLyBSZWYgdG8gdGhlIHJlYWN0IG5vZGUsIGl0IG1heSBiZSBhIEhUTUxFbGVtZW50XG4gICAgdmFyIG5vZGVSZWYgPSB1c2VSZWYoKTtcbiAgICAvLyBSZWYgdG8gdGhlIGRvbSB3cmFwcGVyIGluIGNhc2UgcmVmIGNhbiBub3QgcGFzcyB0byBIVE1MRWxlbWVudFxuICAgIHZhciB3cmFwcGVyTm9kZVJlZiA9IHVzZVJlZigpO1xuICAgIGZ1bmN0aW9uIGdldERvbUVsZW1lbnQoKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBIZXJlIHdlJ3JlIGF2b2lkaW5nIGNhbGwgZm9yIGZpbmRET01Ob2RlIHNpbmNlIGl0J3MgZGVwcmVjYXRlZFxuICAgICAgICAvLyBpbiBzdHJpY3QgbW9kZS4gV2UncmUgY2FsbGluZyBpdCBvbmx5IHdoZW4gbm9kZSByZWYgaXMgbm90XG4gICAgICAgIC8vIGFuIGluc3RhbmNlIG9mIERPTSBIVE1MRWxlbWVudC4gT3RoZXJ3aXNlIHVzZVxuICAgICAgICAvLyBmaW5kRE9NTm9kZSBhcyBhIGZpbmFsIHJlc29ydFxuICAgICAgICByZXR1cm4gbm9kZVJlZi5jdXJyZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPyBub2RlUmVmLmN1cnJlbnQgOiBmaW5kRE9NTm9kZSh3cmFwcGVyTm9kZVJlZi5jdXJyZW50KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gT25seSBoYXBwZW4gd2hlbiBgbW90aW9uRGVhZGxpbmVgIHRyaWdnZXIgYnV0IGVsZW1lbnQgcmVtb3ZlZC5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciBfdXNlU3RhdHVzID0gdXNlU3RhdHVzKHN1cHBvcnRNb3Rpb24sIHZpc2libGUsIGdldERvbUVsZW1lbnQsIHByb3BzKSxcbiAgICAgIF91c2VTdGF0dXMyID0gX3NsaWNlZFRvQXJyYXkoX3VzZVN0YXR1cywgNCksXG4gICAgICBzdGF0dXMgPSBfdXNlU3RhdHVzMlswXSxcbiAgICAgIHN0YXR1c1N0ZXAgPSBfdXNlU3RhdHVzMlsxXSxcbiAgICAgIHN0YXR1c1N0eWxlID0gX3VzZVN0YXR1czJbMl0sXG4gICAgICBtZXJnZWRWaXNpYmxlID0gX3VzZVN0YXR1czJbM107XG5cbiAgICAvLyBSZWNvcmQgd2hldGhlciBjb250ZW50IGhhcyByZW5kZXJlZFxuICAgIC8vIFdpbGwgcmV0dXJuIG51bGwgZm9yIHVuLXJlbmRlcmVkIGV2ZW4gd2hlbiBgcmVtb3ZlT25MZWF2ZT17ZmFsc2V9YFxuICAgIHZhciByZW5kZXJlZFJlZiA9IFJlYWN0LnVzZVJlZihtZXJnZWRWaXNpYmxlKTtcbiAgICBpZiAobWVyZ2VkVmlzaWJsZSkge1xuICAgICAgcmVuZGVyZWRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PSBSZWZzID09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgc2V0Tm9kZVJlZiA9IFJlYWN0LnVzZUNhbGxiYWNrKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICBub2RlUmVmLmN1cnJlbnQgPSBub2RlO1xuICAgICAgZmlsbFJlZihyZWYsIG5vZGUpO1xuICAgIH0sIFtyZWZdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIG1vdGlvbkNoaWxkcmVuO1xuICAgIHZhciBtZXJnZWRQcm9wcyA9IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgZXZlbnRQcm9wcyksIHt9LCB7XG4gICAgICB2aXNpYmxlOiB2aXNpYmxlXG4gICAgfSk7XG4gICAgaWYgKCFjaGlsZHJlbikge1xuICAgICAgLy8gTm8gY2hpbGRyZW5cbiAgICAgIG1vdGlvbkNoaWxkcmVuID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gU1RBVFVTX05PTkUpIHtcbiAgICAgIC8vIFN0YWJsZSBjaGlsZHJlblxuICAgICAgaWYgKG1lcmdlZFZpc2libGUpIHtcbiAgICAgICAgbW90aW9uQ2hpbGRyZW4gPSBjaGlsZHJlbihfb2JqZWN0U3ByZWFkKHt9LCBtZXJnZWRQcm9wcyksIHNldE5vZGVSZWYpO1xuICAgICAgfSBlbHNlIGlmICghcmVtb3ZlT25MZWF2ZSAmJiByZW5kZXJlZFJlZi5jdXJyZW50ICYmIGxlYXZlZENsYXNzTmFtZSkge1xuICAgICAgICBtb3Rpb25DaGlsZHJlbiA9IGNoaWxkcmVuKF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgbWVyZ2VkUHJvcHMpLCB7fSwge1xuICAgICAgICAgIGNsYXNzTmFtZTogbGVhdmVkQ2xhc3NOYW1lXG4gICAgICAgIH0pLCBzZXROb2RlUmVmKTtcbiAgICAgIH0gZWxzZSBpZiAoZm9yY2VSZW5kZXIgfHwgIXJlbW92ZU9uTGVhdmUgJiYgIWxlYXZlZENsYXNzTmFtZSkge1xuICAgICAgICBtb3Rpb25DaGlsZHJlbiA9IGNoaWxkcmVuKF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgbWVyZ2VkUHJvcHMpLCB7fSwge1xuICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBkaXNwbGF5OiAnbm9uZSdcbiAgICAgICAgICB9XG4gICAgICAgIH0pLCBzZXROb2RlUmVmKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1vdGlvbkNoaWxkcmVuID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIF9jbGFzc05hbWVzO1xuICAgICAgLy8gSW4gbW90aW9uXG4gICAgICB2YXIgc3RhdHVzU3VmZml4O1xuICAgICAgaWYgKHN0YXR1c1N0ZXAgPT09IFNURVBfUFJFUEFSRSkge1xuICAgICAgICBzdGF0dXNTdWZmaXggPSAncHJlcGFyZSc7XG4gICAgICB9IGVsc2UgaWYgKGlzQWN0aXZlKHN0YXR1c1N0ZXApKSB7XG4gICAgICAgIHN0YXR1c1N1ZmZpeCA9ICdhY3RpdmUnO1xuICAgICAgfSBlbHNlIGlmIChzdGF0dXNTdGVwID09PSBTVEVQX1NUQVJUKSB7XG4gICAgICAgIHN0YXR1c1N1ZmZpeCA9ICdzdGFydCc7XG4gICAgICB9XG4gICAgICB2YXIgbW90aW9uQ2xzID0gZ2V0VHJhbnNpdGlvbk5hbWUobW90aW9uTmFtZSwgXCJcIi5jb25jYXQoc3RhdHVzLCBcIi1cIikuY29uY2F0KHN0YXR1c1N1ZmZpeCkpO1xuICAgICAgbW90aW9uQ2hpbGRyZW4gPSBjaGlsZHJlbihfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIG1lcmdlZFByb3BzKSwge30sIHtcbiAgICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWVzKGdldFRyYW5zaXRpb25OYW1lKG1vdGlvbk5hbWUsIHN0YXR1cyksIChfY2xhc3NOYW1lcyA9IHt9LCBfZGVmaW5lUHJvcGVydHkoX2NsYXNzTmFtZXMsIG1vdGlvbkNscywgbW90aW9uQ2xzICYmIHN0YXR1c1N1ZmZpeCksIF9kZWZpbmVQcm9wZXJ0eShfY2xhc3NOYW1lcywgbW90aW9uTmFtZSwgdHlwZW9mIG1vdGlvbk5hbWUgPT09ICdzdHJpbmcnKSwgX2NsYXNzTmFtZXMpKSxcbiAgICAgICAgc3R5bGU6IHN0YXR1c1N0eWxlXG4gICAgICB9KSwgc2V0Tm9kZVJlZik7XG4gICAgfVxuXG4gICAgLy8gQXV0byBpbmplY3QgcmVmIGlmIGNoaWxkIG5vZGUgbm90IGhhdmUgYHJlZmAgcHJvcHNcbiAgICBpZiAoIC8qI19fUFVSRV9fKi9SZWFjdC5pc1ZhbGlkRWxlbWVudChtb3Rpb25DaGlsZHJlbikgJiYgc3VwcG9ydFJlZihtb3Rpb25DaGlsZHJlbikpIHtcbiAgICAgIHZhciBfcmVmID0gbW90aW9uQ2hpbGRyZW4sXG4gICAgICAgIG9yaWdpbk5vZGVSZWYgPSBfcmVmLnJlZjtcbiAgICAgIGlmICghb3JpZ2luTm9kZVJlZikge1xuICAgICAgICBtb3Rpb25DaGlsZHJlbiA9IC8qI19fUFVSRV9fKi9SZWFjdC5jbG9uZUVsZW1lbnQobW90aW9uQ2hpbGRyZW4sIHtcbiAgICAgICAgICByZWY6IHNldE5vZGVSZWZcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChEb21XcmFwcGVyLCB7XG4gICAgICByZWY6IHdyYXBwZXJOb2RlUmVmXG4gICAgfSwgbW90aW9uQ2hpbGRyZW4pO1xuICB9KTtcbiAgQ1NTTW90aW9uLmRpc3BsYXlOYW1lID0gJ0NTU01vdGlvbic7XG4gIHJldHVybiBDU1NNb3Rpb247XG59XG5leHBvcnQgZGVmYXVsdCBnZW5DU1NNb3Rpb24oc3VwcG9ydFRyYW5zaXRpb24pOyIsImltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX3R5cGVvZiBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vdHlwZW9mXCI7XG5leHBvcnQgdmFyIFNUQVRVU19BREQgPSAnYWRkJztcbmV4cG9ydCB2YXIgU1RBVFVTX0tFRVAgPSAna2VlcCc7XG5leHBvcnQgdmFyIFNUQVRVU19SRU1PVkUgPSAncmVtb3ZlJztcbmV4cG9ydCB2YXIgU1RBVFVTX1JFTU9WRUQgPSAncmVtb3ZlZCc7XG5leHBvcnQgZnVuY3Rpb24gd3JhcEtleVRvT2JqZWN0KGtleSkge1xuICB2YXIga2V5T2JqO1xuICBpZiAoa2V5ICYmIF90eXBlb2Yoa2V5KSA9PT0gJ29iamVjdCcgJiYgJ2tleScgaW4ga2V5KSB7XG4gICAga2V5T2JqID0ga2V5O1xuICB9IGVsc2Uge1xuICAgIGtleU9iaiA9IHtcbiAgICAgIGtleToga2V5XG4gICAgfTtcbiAgfVxuICByZXR1cm4gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBrZXlPYmopLCB7fSwge1xuICAgIGtleTogU3RyaW5nKGtleU9iai5rZXkpXG4gIH0pO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlS2V5cygpIHtcbiAgdmFyIGtleXMgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFtdO1xuICByZXR1cm4ga2V5cy5tYXAod3JhcEtleVRvT2JqZWN0KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkaWZmS2V5cygpIHtcbiAgdmFyIHByZXZLZXlzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbXTtcbiAgdmFyIGN1cnJlbnRLZXlzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBbXTtcbiAgdmFyIGxpc3QgPSBbXTtcbiAgdmFyIGN1cnJlbnRJbmRleCA9IDA7XG4gIHZhciBjdXJyZW50TGVuID0gY3VycmVudEtleXMubGVuZ3RoO1xuICB2YXIgcHJldktleU9iamVjdHMgPSBwYXJzZUtleXMocHJldktleXMpO1xuICB2YXIgY3VycmVudEtleU9iamVjdHMgPSBwYXJzZUtleXMoY3VycmVudEtleXMpO1xuXG4gIC8vIENoZWNrIHByZXYga2V5cyB0byBpbnNlcnQgb3Iga2VlcFxuICBwcmV2S2V5T2JqZWN0cy5mb3JFYWNoKGZ1bmN0aW9uIChrZXlPYmopIHtcbiAgICB2YXIgaGl0ID0gZmFsc2U7XG4gICAgZm9yICh2YXIgaSA9IGN1cnJlbnRJbmRleDsgaSA8IGN1cnJlbnRMZW47IGkgKz0gMSkge1xuICAgICAgdmFyIGN1cnJlbnRLZXlPYmogPSBjdXJyZW50S2V5T2JqZWN0c1tpXTtcbiAgICAgIGlmIChjdXJyZW50S2V5T2JqLmtleSA9PT0ga2V5T2JqLmtleSkge1xuICAgICAgICAvLyBOZXcgYWRkZWQga2V5cyBzaG91bGQgYWRkIGJlZm9yZSBjdXJyZW50IGtleVxuICAgICAgICBpZiAoY3VycmVudEluZGV4IDwgaSkge1xuICAgICAgICAgIGxpc3QgPSBsaXN0LmNvbmNhdChjdXJyZW50S2V5T2JqZWN0cy5zbGljZShjdXJyZW50SW5kZXgsIGkpLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICByZXR1cm4gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBvYmopLCB7fSwge1xuICAgICAgICAgICAgICBzdGF0dXM6IFNUQVRVU19BRERcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pKTtcbiAgICAgICAgICBjdXJyZW50SW5kZXggPSBpO1xuICAgICAgICB9XG4gICAgICAgIGxpc3QucHVzaChfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe30sIGN1cnJlbnRLZXlPYmopLCB7fSwge1xuICAgICAgICAgIHN0YXR1czogU1RBVFVTX0tFRVBcbiAgICAgICAgfSkpO1xuICAgICAgICBjdXJyZW50SW5kZXggKz0gMTtcbiAgICAgICAgaGl0ID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgbm90IGhpdCwgaXQgbWVhbnMga2V5IGlzIHJlbW92ZWRcbiAgICBpZiAoIWhpdCkge1xuICAgICAgbGlzdC5wdXNoKF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwga2V5T2JqKSwge30sIHtcbiAgICAgICAgc3RhdHVzOiBTVEFUVVNfUkVNT1ZFXG4gICAgICB9KSk7XG4gICAgfVxuICB9KTtcblxuICAvLyBBZGQgcmVzdCB0byB0aGUgbGlzdFxuICBpZiAoY3VycmVudEluZGV4IDwgY3VycmVudExlbikge1xuICAgIGxpc3QgPSBsaXN0LmNvbmNhdChjdXJyZW50S2V5T2JqZWN0cy5zbGljZShjdXJyZW50SW5kZXgpLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICByZXR1cm4gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBvYmopLCB7fSwge1xuICAgICAgICBzdGF0dXM6IFNUQVRVU19BRERcbiAgICAgIH0pO1xuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXJnZSBzYW1lIGtleSB3aGVuIGl0IHJlbW92ZSBhbmQgYWRkIGFnYWluOlxuICAgKiAgICBbMSAtIGFkZCwgMiAtIGtlZXAsIDEgLSByZW1vdmVdIC0+IFsxIC0ga2VlcCwgMiAtIGtlZXBdXG4gICAqL1xuICB2YXIga2V5cyA9IHt9O1xuICBsaXN0LmZvckVhY2goZnVuY3Rpb24gKF9yZWYpIHtcbiAgICB2YXIga2V5ID0gX3JlZi5rZXk7XG4gICAga2V5c1trZXldID0gKGtleXNba2V5XSB8fCAwKSArIDE7XG4gIH0pO1xuICB2YXIgZHVwbGljYXRlZEtleXMgPSBPYmplY3Qua2V5cyhrZXlzKS5maWx0ZXIoZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiBrZXlzW2tleV0gPiAxO1xuICB9KTtcbiAgZHVwbGljYXRlZEtleXMuZm9yRWFjaChmdW5jdGlvbiAobWF0Y2hLZXkpIHtcbiAgICAvLyBSZW1vdmUgYFNUQVRVU19SRU1PVkVgIG5vZGUuXG4gICAgbGlzdCA9IGxpc3QuZmlsdGVyKGZ1bmN0aW9uIChfcmVmMikge1xuICAgICAgdmFyIGtleSA9IF9yZWYyLmtleSxcbiAgICAgICAgc3RhdHVzID0gX3JlZjIuc3RhdHVzO1xuICAgICAgcmV0dXJuIGtleSAhPT0gbWF0Y2hLZXkgfHwgc3RhdHVzICE9PSBTVEFUVVNfUkVNT1ZFO1xuICAgIH0pO1xuXG4gICAgLy8gVXBkYXRlIGBTVEFUVVNfQUREYCB0byBgU1RBVFVTX0tFRVBgXG4gICAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChub2RlKSB7XG4gICAgICBpZiAobm9kZS5rZXkgPT09IG1hdGNoS2V5KSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICBub2RlLnN0YXR1cyA9IFNUQVRVU19LRUVQO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGxpc3Q7XG59IiwiaW1wb3J0IF9leHRlbmRzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9leHRlbmRzXCI7XG5pbXBvcnQgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiO1xuaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCBfY2xhc3NDYWxsQ2hlY2sgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NsYXNzQ2FsbENoZWNrXCI7XG5pbXBvcnQgX2NyZWF0ZUNsYXNzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9jcmVhdGVDbGFzc1wiO1xuaW1wb3J0IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiO1xuaW1wb3J0IF9pbmhlcml0cyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vaW5oZXJpdHNcIjtcbmltcG9ydCBfY3JlYXRlU3VwZXIgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2NyZWF0ZVN1cGVyXCI7XG5pbXBvcnQgX2RlZmluZVByb3BlcnR5IGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9kZWZpbmVQcm9wZXJ0eVwiO1xudmFyIF9leGNsdWRlZCA9IFtcImNvbXBvbmVudFwiLCBcImNoaWxkcmVuXCIsIFwib25WaXNpYmxlQ2hhbmdlZFwiLCBcIm9uQWxsUmVtb3ZlZFwiXSxcbiAgX2V4Y2x1ZGVkMiA9IFtcInN0YXR1c1wiXTtcbi8qIGVzbGludCByZWFjdC9wcm9wLXR5cGVzOiAwICovXG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgT3JpZ2luQ1NTTW90aW9uIGZyb20gXCIuL0NTU01vdGlvblwiO1xuaW1wb3J0IHsgc3VwcG9ydFRyYW5zaXRpb24gfSBmcm9tIFwiLi91dGlsL21vdGlvblwiO1xuaW1wb3J0IHsgU1RBVFVTX0FERCwgU1RBVFVTX0tFRVAsIFNUQVRVU19SRU1PVkUsIFNUQVRVU19SRU1PVkVELCBkaWZmS2V5cywgcGFyc2VLZXlzIH0gZnJvbSBcIi4vdXRpbC9kaWZmXCI7XG52YXIgTU9USU9OX1BST1BfTkFNRVMgPSBbJ2V2ZW50UHJvcHMnLCAndmlzaWJsZScsICdjaGlsZHJlbicsICdtb3Rpb25OYW1lJywgJ21vdGlvbkFwcGVhcicsICdtb3Rpb25FbnRlcicsICdtb3Rpb25MZWF2ZScsICdtb3Rpb25MZWF2ZUltbWVkaWF0ZWx5JywgJ21vdGlvbkRlYWRsaW5lJywgJ3JlbW92ZU9uTGVhdmUnLCAnbGVhdmVkQ2xhc3NOYW1lJywgJ29uQXBwZWFyU3RhcnQnLCAnb25BcHBlYXJBY3RpdmUnLCAnb25BcHBlYXJFbmQnLCAnb25FbnRlclN0YXJ0JywgJ29uRW50ZXJBY3RpdmUnLCAnb25FbnRlckVuZCcsICdvbkxlYXZlU3RhcnQnLCAnb25MZWF2ZUFjdGl2ZScsICdvbkxlYXZlRW5kJ107XG4vKipcbiAqIEdlbmVyYXRlIGEgQ1NTTW90aW9uTGlzdCBjb21wb25lbnQgd2l0aCBjb25maWdcbiAqIEBwYXJhbSB0cmFuc2l0aW9uU3VwcG9ydCBObyBuZWVkIHNpbmNlIENTU01vdGlvbkxpc3Qgbm8gbG9uZ2VyIGRlcGVuZHMgb24gdHJhbnNpdGlvbiBzdXBwb3J0XG4gKiBAcGFyYW0gQ1NTTW90aW9uIENTU01vdGlvbiBjb21wb25lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbkNTU01vdGlvbkxpc3QodHJhbnNpdGlvblN1cHBvcnQpIHtcbiAgdmFyIENTU01vdGlvbiA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogT3JpZ2luQ1NTTW90aW9uO1xuICB2YXIgQ1NTTW90aW9uTGlzdCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhDU1NNb3Rpb25MaXN0LCBfUmVhY3QkQ29tcG9uZW50KTtcbiAgICB2YXIgX3N1cGVyID0gX2NyZWF0ZVN1cGVyKENTU01vdGlvbkxpc3QpO1xuICAgIGZ1bmN0aW9uIENTU01vdGlvbkxpc3QoKSB7XG4gICAgICB2YXIgX3RoaXM7XG4gICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ1NTTW90aW9uTGlzdCk7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgIH1cbiAgICAgIF90aGlzID0gX3N1cGVyLmNhbGwuYXBwbHkoX3N1cGVyLCBbdGhpc10uY29uY2F0KGFyZ3MpKTtcbiAgICAgIF9kZWZpbmVQcm9wZXJ0eShfYXNzZXJ0VGhpc0luaXRpYWxpemVkKF90aGlzKSwgXCJzdGF0ZVwiLCB7XG4gICAgICAgIGtleUVudGl0aWVzOiBbXVxuICAgICAgfSk7XG4gICAgICBfZGVmaW5lUHJvcGVydHkoX2Fzc2VydFRoaXNJbml0aWFsaXplZChfdGhpcyksIFwicmVtb3ZlS2V5XCIsIGZ1bmN0aW9uIChyZW1vdmVLZXkpIHtcbiAgICAgICAgdmFyIGtleUVudGl0aWVzID0gX3RoaXMuc3RhdGUua2V5RW50aXRpZXM7XG4gICAgICAgIHZhciBuZXh0S2V5RW50aXRpZXMgPSBrZXlFbnRpdGllcy5tYXAoZnVuY3Rpb24gKGVudGl0eSkge1xuICAgICAgICAgIGlmIChlbnRpdHkua2V5ICE9PSByZW1vdmVLZXkpIHJldHVybiBlbnRpdHk7XG4gICAgICAgICAgcmV0dXJuIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgZW50aXR5KSwge30sIHtcbiAgICAgICAgICAgIHN0YXR1czogU1RBVFVTX1JFTU9WRURcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIF90aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICBrZXlFbnRpdGllczogbmV4dEtleUVudGl0aWVzXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmV4dEtleUVudGl0aWVzLmZpbHRlcihmdW5jdGlvbiAoX3JlZikge1xuICAgICAgICAgIHZhciBzdGF0dXMgPSBfcmVmLnN0YXR1cztcbiAgICAgICAgICByZXR1cm4gc3RhdHVzICE9PSBTVEFUVVNfUkVNT1ZFRDtcbiAgICAgICAgfSkubGVuZ3RoO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gX3RoaXM7XG4gICAgfVxuICAgIF9jcmVhdGVDbGFzcyhDU1NNb3Rpb25MaXN0LCBbe1xuICAgICAga2V5OiBcInJlbmRlclwiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG4gICAgICAgIHZhciBrZXlFbnRpdGllcyA9IHRoaXMuc3RhdGUua2V5RW50aXRpZXM7XG4gICAgICAgIHZhciBfdGhpcyRwcm9wcyA9IHRoaXMucHJvcHMsXG4gICAgICAgICAgY29tcG9uZW50ID0gX3RoaXMkcHJvcHMuY29tcG9uZW50LFxuICAgICAgICAgIGNoaWxkcmVuID0gX3RoaXMkcHJvcHMuY2hpbGRyZW4sXG4gICAgICAgICAgX29uVmlzaWJsZUNoYW5nZWQgPSBfdGhpcyRwcm9wcy5vblZpc2libGVDaGFuZ2VkLFxuICAgICAgICAgIG9uQWxsUmVtb3ZlZCA9IF90aGlzJHByb3BzLm9uQWxsUmVtb3ZlZCxcbiAgICAgICAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoX3RoaXMkcHJvcHMsIF9leGNsdWRlZCk7XG4gICAgICAgIHZhciBDb21wb25lbnQgPSBjb21wb25lbnQgfHwgUmVhY3QuRnJhZ21lbnQ7XG4gICAgICAgIHZhciBtb3Rpb25Qcm9wcyA9IHt9O1xuICAgICAgICBNT1RJT05fUFJPUF9OQU1FUy5mb3JFYWNoKGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgICAgICAgbW90aW9uUHJvcHNbcHJvcF0gPSByZXN0UHJvcHNbcHJvcF07XG4gICAgICAgICAgZGVsZXRlIHJlc3RQcm9wc1twcm9wXTtcbiAgICAgICAgfSk7XG4gICAgICAgIGRlbGV0ZSByZXN0UHJvcHMua2V5cztcbiAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KENvbXBvbmVudCwgcmVzdFByb3BzLCBrZXlFbnRpdGllcy5tYXAoZnVuY3Rpb24gKF9yZWYyKSB7XG4gICAgICAgICAgdmFyIHN0YXR1cyA9IF9yZWYyLnN0YXR1cyxcbiAgICAgICAgICAgIGV2ZW50UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMoX3JlZjIsIF9leGNsdWRlZDIpO1xuICAgICAgICAgIHZhciB2aXNpYmxlID0gc3RhdHVzID09PSBTVEFUVVNfQUREIHx8IHN0YXR1cyA9PT0gU1RBVFVTX0tFRVA7XG4gICAgICAgICAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KENTU01vdGlvbiwgX2V4dGVuZHMoe30sIG1vdGlvblByb3BzLCB7XG4gICAgICAgICAgICBrZXk6IGV2ZW50UHJvcHMua2V5LFxuICAgICAgICAgICAgdmlzaWJsZTogdmlzaWJsZSxcbiAgICAgICAgICAgIGV2ZW50UHJvcHM6IGV2ZW50UHJvcHMsXG4gICAgICAgICAgICBvblZpc2libGVDaGFuZ2VkOiBmdW5jdGlvbiBvblZpc2libGVDaGFuZ2VkKGNoYW5nZWRWaXNpYmxlKSB7XG4gICAgICAgICAgICAgIF9vblZpc2libGVDaGFuZ2VkID09PSBudWxsIHx8IF9vblZpc2libGVDaGFuZ2VkID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfb25WaXNpYmxlQ2hhbmdlZChjaGFuZ2VkVmlzaWJsZSwge1xuICAgICAgICAgICAgICAgIGtleTogZXZlbnRQcm9wcy5rZXlcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGlmICghY2hhbmdlZFZpc2libGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzdEtleXNDb3VudCA9IF90aGlzMi5yZW1vdmVLZXkoZXZlbnRQcm9wcy5rZXkpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN0S2V5c0NvdW50ID09PSAwICYmIG9uQWxsUmVtb3ZlZCkge1xuICAgICAgICAgICAgICAgICAgb25BbGxSZW1vdmVkKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksIGNoaWxkcmVuKTtcbiAgICAgICAgfSkpO1xuICAgICAgfVxuICAgIH1dLCBbe1xuICAgICAga2V5OiBcImdldERlcml2ZWRTdGF0ZUZyb21Qcm9wc1wiLFxuICAgICAgdmFsdWU6IGZ1bmN0aW9uIGdldERlcml2ZWRTdGF0ZUZyb21Qcm9wcyhfcmVmMywgX3JlZjQpIHtcbiAgICAgICAgdmFyIGtleXMgPSBfcmVmMy5rZXlzO1xuICAgICAgICB2YXIga2V5RW50aXRpZXMgPSBfcmVmNC5rZXlFbnRpdGllcztcbiAgICAgICAgdmFyIHBhcnNlZEtleU9iamVjdHMgPSBwYXJzZUtleXMoa2V5cyk7XG4gICAgICAgIHZhciBtaXhlZEtleUVudGl0aWVzID0gZGlmZktleXMoa2V5RW50aXRpZXMsIHBhcnNlZEtleU9iamVjdHMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleUVudGl0aWVzOiBtaXhlZEtleUVudGl0aWVzLmZpbHRlcihmdW5jdGlvbiAoZW50aXR5KSB7XG4gICAgICAgICAgICB2YXIgcHJldkVudGl0eSA9IGtleUVudGl0aWVzLmZpbmQoZnVuY3Rpb24gKF9yZWY1KSB7XG4gICAgICAgICAgICAgIHZhciBrZXkgPSBfcmVmNS5rZXk7XG4gICAgICAgICAgICAgIHJldHVybiBlbnRpdHkua2V5ID09PSBrZXk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIGlmIGFscmVhZHkgbWFyayBhcyByZW1vdmVkXG4gICAgICAgICAgICBpZiAocHJldkVudGl0eSAmJiBwcmV2RW50aXR5LnN0YXR1cyA9PT0gU1RBVFVTX1JFTU9WRUQgJiYgZW50aXR5LnN0YXR1cyA9PT0gU1RBVFVTX1JFTU9WRSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBab21iaWVKOiBSZXR1cm4gdGhlIGNvdW50IG9mIHJlc3Qga2V5cy4gSXQncyBzYWZlIHRvIHJlZmFjdG9yIGlmIG5lZWQgbW9yZSBpbmZvLlxuICAgIH1dKTtcbiAgICByZXR1cm4gQ1NTTW90aW9uTGlzdDtcbiAgfShSZWFjdC5Db21wb25lbnQpO1xuICBfZGVmaW5lUHJvcGVydHkoQ1NTTW90aW9uTGlzdCwgXCJkZWZhdWx0UHJvcHNcIiwge1xuICAgIGNvbXBvbmVudDogJ2RpdidcbiAgfSk7XG4gIHJldHVybiBDU1NNb3Rpb25MaXN0O1xufVxuZXhwb3J0IGRlZmF1bHQgZ2VuQ1NTTW90aW9uTGlzdChzdXBwb3J0VHJhbnNpdGlvbik7IiwiaW1wb3J0IENTU01vdGlvbiBmcm9tIFwiLi9DU1NNb3Rpb25cIjtcbmltcG9ydCBDU1NNb3Rpb25MaXN0IGZyb20gXCIuL0NTU01vdGlvbkxpc3RcIjtcbmV4cG9ydCB7IGRlZmF1bHQgYXMgUHJvdmlkZXIgfSBmcm9tIFwiLi9jb250ZXh0XCI7XG5leHBvcnQgeyBDU1NNb3Rpb25MaXN0IH07XG5leHBvcnQgZGVmYXVsdCBDU1NNb3Rpb247IiwiaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcnJvdyhwcm9wcykge1xuICB2YXIgcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgIGFsaWduID0gcHJvcHMuYWxpZ24sXG4gICAgYXJyb3cgPSBwcm9wcy5hcnJvdyxcbiAgICBhcnJvd1BvcyA9IHByb3BzLmFycm93UG9zO1xuICB2YXIgX3JlZiA9IGFycm93IHx8IHt9LFxuICAgIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLFxuICAgIGNvbnRlbnQgPSBfcmVmLmNvbnRlbnQ7XG4gIHZhciBfYXJyb3dQb3MkeCA9IGFycm93UG9zLngsXG4gICAgeCA9IF9hcnJvd1BvcyR4ID09PSB2b2lkIDAgPyAwIDogX2Fycm93UG9zJHgsXG4gICAgX2Fycm93UG9zJHkgPSBhcnJvd1Bvcy55LFxuICAgIHkgPSBfYXJyb3dQb3MkeSA9PT0gdm9pZCAwID8gMCA6IF9hcnJvd1BvcyR5O1xuICB2YXIgYXJyb3dSZWYgPSBSZWFjdC51c2VSZWYoKTtcblxuICAvLyBTa2lwIGlmIG5vIGFsaWduXG4gIGlmICghYWxpZ24gfHwgIWFsaWduLnBvaW50cykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZhciBhbGlnblN0eWxlID0ge1xuICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXG4gIH07XG5cbiAgLy8gU2tpcCBpZiBubyBuZWVkIHRvIGFsaWduXG4gIGlmIChhbGlnbi5hdXRvQXJyb3cgIT09IGZhbHNlKSB7XG4gICAgdmFyIHBvcHVwUG9pbnRzID0gYWxpZ24ucG9pbnRzWzBdO1xuICAgIHZhciB0YXJnZXRQb2ludHMgPSBhbGlnbi5wb2ludHNbMV07XG4gICAgdmFyIHBvcHVwVEIgPSBwb3B1cFBvaW50c1swXTtcbiAgICB2YXIgcG9wdXBMUiA9IHBvcHVwUG9pbnRzWzFdO1xuICAgIHZhciB0YXJnZXRUQiA9IHRhcmdldFBvaW50c1swXTtcbiAgICB2YXIgdGFyZ2V0TFIgPSB0YXJnZXRQb2ludHNbMV07XG5cbiAgICAvLyBUb3AgJiBCb3R0b21cbiAgICBpZiAocG9wdXBUQiA9PT0gdGFyZ2V0VEIgfHwgIVsndCcsICdiJ10uaW5jbHVkZXMocG9wdXBUQikpIHtcbiAgICAgIGFsaWduU3R5bGUudG9wID0geTtcbiAgICB9IGVsc2UgaWYgKHBvcHVwVEIgPT09ICd0Jykge1xuICAgICAgYWxpZ25TdHlsZS50b3AgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbGlnblN0eWxlLmJvdHRvbSA9IDA7XG4gICAgfVxuXG4gICAgLy8gTGVmdCAmIFJpZ2h0XG4gICAgaWYgKHBvcHVwTFIgPT09IHRhcmdldExSIHx8ICFbJ2wnLCAnciddLmluY2x1ZGVzKHBvcHVwTFIpKSB7XG4gICAgICBhbGlnblN0eWxlLmxlZnQgPSB4O1xuICAgIH0gZWxzZSBpZiAocG9wdXBMUiA9PT0gJ2wnKSB7XG4gICAgICBhbGlnblN0eWxlLmxlZnQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBhbGlnblN0eWxlLnJpZ2h0ID0gMDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICByZWY6IGFycm93UmVmLFxuICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyhcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWFycm93XCIpLCBjbGFzc05hbWUpLFxuICAgIHN0eWxlOiBhbGlnblN0eWxlXG4gIH0sIGNvbnRlbnQpO1xufSIsImltcG9ydCBfZXh0ZW5kcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vZXh0ZW5kc1wiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgQ1NTTW90aW9uIGZyb20gJ3JjLW1vdGlvbic7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNYXNrKHByb3BzKSB7XG4gIHZhciBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgb3BlbiA9IHByb3BzLm9wZW4sXG4gICAgekluZGV4ID0gcHJvcHMuekluZGV4LFxuICAgIG1hc2sgPSBwcm9wcy5tYXNrLFxuICAgIG1vdGlvbiA9IHByb3BzLm1vdGlvbjtcbiAgaWYgKCFtYXNrKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KENTU01vdGlvbiwgX2V4dGVuZHMoe30sIG1vdGlvbiwge1xuICAgIG1vdGlvbkFwcGVhcjogdHJ1ZSxcbiAgICB2aXNpYmxlOiBvcGVuLFxuICAgIHJlbW92ZU9uTGVhdmU6IHRydWVcbiAgfSksIGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgdmFyIGNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lO1xuICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICBzdHlsZToge1xuICAgICAgICB6SW5kZXg6IHpJbmRleFxuICAgICAgfSxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyhcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLW1hc2tcIiksIGNsYXNzTmFtZSlcbiAgICB9KTtcbiAgfSk7XG59IiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xudmFyIFBvcHVwQ29udGVudCA9IC8qI19fUFVSRV9fKi9SZWFjdC5tZW1vKGZ1bmN0aW9uIChfcmVmKSB7XG4gIHZhciBjaGlsZHJlbiA9IF9yZWYuY2hpbGRyZW47XG4gIHJldHVybiBjaGlsZHJlbjtcbn0sIGZ1bmN0aW9uIChfLCBuZXh0KSB7XG4gIHJldHVybiBuZXh0LmNhY2hlO1xufSk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBQb3B1cENvbnRlbnQuZGlzcGxheU5hbWUgPSAnUG9wdXBDb250ZW50Jztcbn1cbmV4cG9ydCBkZWZhdWx0IFBvcHVwQ29udGVudDsiLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX3NsaWNlZFRvQXJyYXkgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL3NsaWNlZFRvQXJyYXlcIjtcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IENTU01vdGlvbiBmcm9tICdyYy1tb3Rpb24nO1xuaW1wb3J0IFJlc2l6ZU9ic2VydmVyIGZyb20gJ3JjLXJlc2l6ZS1vYnNlcnZlcic7XG5pbXBvcnQgdXNlTGF5b3V0RWZmZWN0IGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUxheW91dEVmZmVjdFwiO1xuaW1wb3J0IHsgY29tcG9zZVJlZiB9IGZyb20gXCJyYy11dGlsL2VzL3JlZlwiO1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEFycm93IGZyb20gXCIuL0Fycm93XCI7XG5pbXBvcnQgTWFzayBmcm9tIFwiLi9NYXNrXCI7XG5pbXBvcnQgUG9wdXBDb250ZW50IGZyb20gXCIuL1BvcHVwQ29udGVudFwiO1xudmFyIFBvcHVwID0gLyojX19QVVJFX18qL1JlYWN0LmZvcndhcmRSZWYoZnVuY3Rpb24gKHByb3BzLCByZWYpIHtcbiAgdmFyIHBvcHVwID0gcHJvcHMucG9wdXAsXG4gICAgY2xhc3NOYW1lID0gcHJvcHMuY2xhc3NOYW1lLFxuICAgIHByZWZpeENscyA9IHByb3BzLnByZWZpeENscyxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlLFxuICAgIHRhcmdldCA9IHByb3BzLnRhcmdldCxcbiAgICBfb25WaXNpYmxlQ2hhbmdlZCA9IHByb3BzLm9uVmlzaWJsZUNoYW5nZWQsXG4gICAgb3BlbiA9IHByb3BzLm9wZW4sXG4gICAga2VlcERvbSA9IHByb3BzLmtlZXBEb20sXG4gICAgb25DbGljayA9IHByb3BzLm9uQ2xpY2ssXG4gICAgbWFzayA9IHByb3BzLm1hc2ssXG4gICAgYXJyb3cgPSBwcm9wcy5hcnJvdyxcbiAgICBhcnJvd1BvcyA9IHByb3BzLmFycm93UG9zLFxuICAgIGFsaWduID0gcHJvcHMuYWxpZ24sXG4gICAgbW90aW9uID0gcHJvcHMubW90aW9uLFxuICAgIG1hc2tNb3Rpb24gPSBwcm9wcy5tYXNrTW90aW9uLFxuICAgIGZvcmNlUmVuZGVyID0gcHJvcHMuZm9yY2VSZW5kZXIsXG4gICAgZ2V0UG9wdXBDb250YWluZXIgPSBwcm9wcy5nZXRQb3B1cENvbnRhaW5lcixcbiAgICBhdXRvRGVzdHJveSA9IHByb3BzLmF1dG9EZXN0cm95LFxuICAgIFBvcnRhbCA9IHByb3BzLnBvcnRhbCxcbiAgICB6SW5kZXggPSBwcm9wcy56SW5kZXgsXG4gICAgb25Nb3VzZUVudGVyID0gcHJvcHMub25Nb3VzZUVudGVyLFxuICAgIG9uTW91c2VMZWF2ZSA9IHByb3BzLm9uTW91c2VMZWF2ZSxcbiAgICByZWFkeSA9IHByb3BzLnJlYWR5LFxuICAgIG9mZnNldFggPSBwcm9wcy5vZmZzZXRYLFxuICAgIG9mZnNldFkgPSBwcm9wcy5vZmZzZXRZLFxuICAgIG9uQWxpZ24gPSBwcm9wcy5vbkFsaWduLFxuICAgIG9uUHJlcGFyZSA9IHByb3BzLm9uUHJlcGFyZSxcbiAgICBzdHJldGNoID0gcHJvcHMuc3RyZXRjaCxcbiAgICB0YXJnZXRXaWR0aCA9IHByb3BzLnRhcmdldFdpZHRoLFxuICAgIHRhcmdldEhlaWdodCA9IHByb3BzLnRhcmdldEhlaWdodDtcbiAgdmFyIGNoaWxkTm9kZSA9IHR5cGVvZiBwb3B1cCA9PT0gJ2Z1bmN0aW9uJyA/IHBvcHVwKCkgOiBwb3B1cDtcblxuICAvLyBXZSBjYW4gbm90IHJlbW92ZSBob2xkZXIgb25seSB3aGVuIG1vdGlvbiBmaW5pc2hlZC5cbiAgdmFyIGlzTm9kZVZpc2libGUgPSBvcGVuIHx8IGtlZXBEb207XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT0gQ29udGFpbmVyID09PT09PT09PT09PT09PT09PT09PT09PVxuICB2YXIgZ2V0UG9wdXBDb250YWluZXJOZWVkUGFyYW1zID0gKGdldFBvcHVwQ29udGFpbmVyID09PSBudWxsIHx8IGdldFBvcHVwQ29udGFpbmVyID09PSB2b2lkIDAgPyB2b2lkIDAgOiBnZXRQb3B1cENvbnRhaW5lci5sZW5ndGgpID4gMDtcbiAgdmFyIF9SZWFjdCR1c2VTdGF0ZSA9IFJlYWN0LnVzZVN0YXRlKCFnZXRQb3B1cENvbnRhaW5lciB8fCAhZ2V0UG9wdXBDb250YWluZXJOZWVkUGFyYW1zKSxcbiAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICBzaG93ID0gX1JlYWN0JHVzZVN0YXRlMlswXSxcbiAgICBzZXRTaG93ID0gX1JlYWN0JHVzZVN0YXRlMlsxXTtcblxuICAvLyBEZWxheSB0byBzaG93IHNpbmNlIGBnZXRQb3B1cENvbnRhaW5lcmAgbmVlZCB0YXJnZXQgZWxlbWVudFxuICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgIGlmICghc2hvdyAmJiBnZXRQb3B1cENvbnRhaW5lck5lZWRQYXJhbXMgJiYgdGFyZ2V0KSB7XG4gICAgICBzZXRTaG93KHRydWUpO1xuICAgIH1cbiAgfSwgW3Nob3csIGdldFBvcHVwQ29udGFpbmVyTmVlZFBhcmFtcywgdGFyZ2V0XSk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PSBSZW5kZXIgPT09PT09PT09PT09PT09PT09PT09PT09PVxuICBpZiAoIXNob3cpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vID4+Pj4+IE9mZnNldFxuICB2YXIgb2Zmc2V0U3R5bGUgPSByZWFkeSB8fCAhb3BlbiA/IHtcbiAgICBsZWZ0OiBvZmZzZXRYLFxuICAgIHRvcDogb2Zmc2V0WVxuICB9IDoge1xuICAgIGxlZnQ6ICctMTAwMHZ3JyxcbiAgICB0b3A6ICctMTAwMHZoJ1xuICB9O1xuXG4gIC8vID4+Pj4+IE1pc2NcbiAgdmFyIG1pc2NTdHlsZSA9IHt9O1xuICBpZiAoc3RyZXRjaCkge1xuICAgIGlmIChzdHJldGNoLmluY2x1ZGVzKCdoZWlnaHQnKSAmJiB0YXJnZXRIZWlnaHQpIHtcbiAgICAgIG1pc2NTdHlsZS5oZWlnaHQgPSB0YXJnZXRIZWlnaHQ7XG4gICAgfSBlbHNlIGlmIChzdHJldGNoLmluY2x1ZGVzKCdtaW5IZWlnaHQnKSAmJiB0YXJnZXRIZWlnaHQpIHtcbiAgICAgIG1pc2NTdHlsZS5taW5IZWlnaHQgPSB0YXJnZXRIZWlnaHQ7XG4gICAgfVxuICAgIGlmIChzdHJldGNoLmluY2x1ZGVzKCd3aWR0aCcpICYmIHRhcmdldFdpZHRoKSB7XG4gICAgICBtaXNjU3R5bGUud2lkdGggPSB0YXJnZXRXaWR0aDtcbiAgICB9IGVsc2UgaWYgKHN0cmV0Y2guaW5jbHVkZXMoJ21pbldpZHRoJykgJiYgdGFyZ2V0V2lkdGgpIHtcbiAgICAgIG1pc2NTdHlsZS5taW5XaWR0aCA9IHRhcmdldFdpZHRoO1xuICAgIH1cbiAgfVxuICBpZiAoIW9wZW4pIHtcbiAgICBtaXNjU3R5bGUucG9pbnRlckV2ZW50cyA9ICdub25lJztcbiAgfVxuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUG9ydGFsLCB7XG4gICAgb3BlbjogZm9yY2VSZW5kZXIgfHwgaXNOb2RlVmlzaWJsZSxcbiAgICBnZXRDb250YWluZXI6IGdldFBvcHVwQ29udGFpbmVyICYmIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBnZXRQb3B1cENvbnRhaW5lcih0YXJnZXQpO1xuICAgIH0sXG4gICAgYXV0b0Rlc3Ryb3k6IGF1dG9EZXN0cm95XG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KE1hc2ssIHtcbiAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICBvcGVuOiBvcGVuLFxuICAgIHpJbmRleDogekluZGV4LFxuICAgIG1hc2s6IG1hc2ssXG4gICAgbW90aW9uOiBtYXNrTW90aW9uXG4gIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChSZXNpemVPYnNlcnZlciwge1xuICAgIG9uUmVzaXplOiBvbkFsaWduLFxuICAgIGRpc2FibGVkOiAhb3BlblxuICB9LCBmdW5jdGlvbiAocmVzaXplT2JzZXJ2ZXJSZWYpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoQ1NTTW90aW9uLCBfZXh0ZW5kcyh7XG4gICAgICBtb3Rpb25BcHBlYXI6IHRydWUsXG4gICAgICBtb3Rpb25FbnRlcjogdHJ1ZSxcbiAgICAgIG1vdGlvbkxlYXZlOiB0cnVlLFxuICAgICAgcmVtb3ZlT25MZWF2ZTogZmFsc2UsXG4gICAgICBmb3JjZVJlbmRlcjogZm9yY2VSZW5kZXIsXG4gICAgICBsZWF2ZWRDbGFzc05hbWU6IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItaGlkZGVuXCIpXG4gICAgfSwgbW90aW9uLCB7XG4gICAgICBvbkFwcGVhclByZXBhcmU6IG9uUHJlcGFyZSxcbiAgICAgIG9uRW50ZXJQcmVwYXJlOiBvblByZXBhcmUsXG4gICAgICB2aXNpYmxlOiBvcGVuLFxuICAgICAgb25WaXNpYmxlQ2hhbmdlZDogZnVuY3Rpb24gb25WaXNpYmxlQ2hhbmdlZChuZXh0VmlzaWJsZSkge1xuICAgICAgICB2YXIgX21vdGlvbiRvblZpc2libGVDaGFuO1xuICAgICAgICBtb3Rpb24gPT09IG51bGwgfHwgbW90aW9uID09PSB2b2lkIDAgPyB2b2lkIDAgOiAoX21vdGlvbiRvblZpc2libGVDaGFuID0gbW90aW9uLm9uVmlzaWJsZUNoYW5nZWQpID09PSBudWxsIHx8IF9tb3Rpb24kb25WaXNpYmxlQ2hhbiA9PT0gdm9pZCAwID8gdm9pZCAwIDogX21vdGlvbiRvblZpc2libGVDaGFuLmNhbGwobW90aW9uLCBuZXh0VmlzaWJsZSk7XG4gICAgICAgIF9vblZpc2libGVDaGFuZ2VkKG5leHRWaXNpYmxlKTtcbiAgICAgIH1cbiAgICB9KSwgZnVuY3Rpb24gKF9yZWYsIG1vdGlvblJlZikge1xuICAgICAgdmFyIG1vdGlvbkNsYXNzTmFtZSA9IF9yZWYuY2xhc3NOYW1lLFxuICAgICAgICBtb3Rpb25TdHlsZSA9IF9yZWYuc3R5bGU7XG4gICAgICB2YXIgY2xzID0gY2xhc3NOYW1lcyhwcmVmaXhDbHMsIG1vdGlvbkNsYXNzTmFtZSwgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybiAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7XG4gICAgICAgIHJlZjogY29tcG9zZVJlZihyZXNpemVPYnNlcnZlclJlZiwgcmVmLCBtb3Rpb25SZWYpLFxuICAgICAgICBjbGFzc05hbWU6IGNscyxcbiAgICAgICAgc3R5bGU6IF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKF9vYmplY3RTcHJlYWQoe1xuICAgICAgICAgICctLWFycm93LXgnOiBcIlwiLmNvbmNhdChhcnJvd1Bvcy54IHx8IDAsIFwicHhcIiksXG4gICAgICAgICAgJy0tYXJyb3cteSc6IFwiXCIuY29uY2F0KGFycm93UG9zLnkgfHwgMCwgXCJweFwiKVxuICAgICAgICB9LCBvZmZzZXRTdHlsZSksIG1pc2NTdHlsZSksIG1vdGlvblN0eWxlKSwge30sIHtcbiAgICAgICAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICAgICAgICB6SW5kZXg6IHpJbmRleFxuICAgICAgICB9LCBzdHlsZSksXG4gICAgICAgIG9uTW91c2VFbnRlcjogb25Nb3VzZUVudGVyLFxuICAgICAgICBvbk1vdXNlTGVhdmU6IG9uTW91c2VMZWF2ZSxcbiAgICAgICAgb25DbGljazogb25DbGlja1xuICAgICAgfSwgYXJyb3cgJiYgLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoQXJyb3csIHtcbiAgICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICAgIGFycm93OiBhcnJvdyxcbiAgICAgICAgYXJyb3dQb3M6IGFycm93UG9zLFxuICAgICAgICBhbGlnbjogYWxpZ25cbiAgICAgIH0pLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQb3B1cENvbnRlbnQsIHtcbiAgICAgICAgY2FjaGU6ICFvcGVuXG4gICAgICB9LCBjaGlsZE5vZGUpKTtcbiAgICB9KTtcbiAgfSkpO1xufSk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICBQb3B1cC5kaXNwbGF5TmFtZSA9ICdQb3B1cCc7XG59XG5leHBvcnQgZGVmYXVsdCBQb3B1cDsiLCJpbXBvcnQgeyBmaWxsUmVmLCBzdXBwb3J0UmVmLCB1c2VDb21wb3NlUmVmIH0gZnJvbSBcInJjLXV0aWwvZXMvcmVmXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG52YXIgVHJpZ2dlcldyYXBwZXIgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICB2YXIgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbixcbiAgICBnZXRUcmlnZ2VyRE9NTm9kZSA9IHByb3BzLmdldFRyaWdnZXJET01Ob2RlO1xuICB2YXIgY2FuVXNlUmVmID0gc3VwcG9ydFJlZihjaGlsZHJlbik7XG5cbiAgLy8gV2hlbiB1c2UgYGdldFRyaWdnZXJET01Ob2RlYCwgd2Ugc2hvdWxkIGRvIGFkZGl0aW9uYWwgd29yayB0byBnZXQgdGhlIHJlYWwgZG9tXG4gIHZhciBzZXRSZWYgPSBSZWFjdC51c2VDYWxsYmFjayhmdW5jdGlvbiAobm9kZSkge1xuICAgIGZpbGxSZWYocmVmLCBnZXRUcmlnZ2VyRE9NTm9kZSA/IGdldFRyaWdnZXJET01Ob2RlKG5vZGUpIDogbm9kZSk7XG4gIH0sIFtnZXRUcmlnZ2VyRE9NTm9kZV0pO1xuICB2YXIgbWVyZ2VkUmVmID0gdXNlQ29tcG9zZVJlZihzZXRSZWYsIGNoaWxkcmVuLnJlZik7XG4gIHJldHVybiBjYW5Vc2VSZWYgPyAvKiNfX1BVUkVfXyovUmVhY3QuY2xvbmVFbGVtZW50KGNoaWxkcmVuLCB7XG4gICAgcmVmOiBtZXJnZWRSZWZcbiAgfSkgOiBjaGlsZHJlbjtcbn0pO1xuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgVHJpZ2dlcldyYXBwZXIuZGlzcGxheU5hbWUgPSAnVHJpZ2dlcldyYXBwZXInO1xufVxuZXhwb3J0IGRlZmF1bHQgVHJpZ2dlcldyYXBwZXI7IiwiaW1wb3J0IF9vYmplY3RTcHJlYWQgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL29iamVjdFNwcmVhZDJcIjtcbmltcG9ydCBfc2xpY2VkVG9BcnJheSBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vc2xpY2VkVG9BcnJheVwiO1xuaW1wb3J0IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyBmcm9tIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9lc20vb2JqZWN0V2l0aG91dFByb3BlcnRpZXNcIjtcbnZhciBfZXhjbHVkZWQgPSBbXCJwcmVmaXhDbHNcIiwgXCJjaGlsZHJlblwiLCBcImFjdGlvblwiLCBcInNob3dBY3Rpb25cIiwgXCJoaWRlQWN0aW9uXCIsIFwicG9wdXBWaXNpYmxlXCIsIFwiZGVmYXVsdFBvcHVwVmlzaWJsZVwiLCBcIm9uUG9wdXBWaXNpYmxlQ2hhbmdlXCIsIFwiYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2VcIiwgXCJtb3VzZUVudGVyRGVsYXlcIiwgXCJtb3VzZUxlYXZlRGVsYXlcIiwgXCJmb2N1c0RlbGF5XCIsIFwiYmx1ckRlbGF5XCIsIFwibWFza1wiLCBcIm1hc2tDbG9zYWJsZVwiLCBcImdldFBvcHVwQ29udGFpbmVyXCIsIFwiZm9yY2VSZW5kZXJcIiwgXCJhdXRvRGVzdHJveVwiLCBcImRlc3Ryb3lQb3B1cE9uSGlkZVwiLCBcInBvcHVwXCIsIFwicG9wdXBDbGFzc05hbWVcIiwgXCJwb3B1cFN0eWxlXCIsIFwicG9wdXBQbGFjZW1lbnRcIiwgXCJidWlsdGluUGxhY2VtZW50c1wiLCBcInBvcHVwQWxpZ25cIiwgXCJ6SW5kZXhcIiwgXCJzdHJldGNoXCIsIFwiZ2V0UG9wdXBDbGFzc05hbWVGcm9tQWxpZ25cIiwgXCJhbGlnblBvaW50XCIsIFwib25Qb3B1cENsaWNrXCIsIFwib25Qb3B1cEFsaWduXCIsIFwiYXJyb3dcIiwgXCJwb3B1cE1vdGlvblwiLCBcIm1hc2tNb3Rpb25cIiwgXCJwb3B1cFRyYW5zaXRpb25OYW1lXCIsIFwicG9wdXBBbmltYXRpb25cIiwgXCJtYXNrVHJhbnNpdGlvbk5hbWVcIiwgXCJtYXNrQW5pbWF0aW9uXCIsIFwiY2xhc3NOYW1lXCIsIFwiZ2V0VHJpZ2dlckRPTU5vZGVcIl07XG5pbXBvcnQgUG9ydGFsIGZyb20gJ0ByYy1jb21wb25lbnQvcG9ydGFsJztcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gJ2NsYXNzbmFtZXMnO1xuaW1wb3J0IFJlc2l6ZU9ic2VydmVyIGZyb20gJ3JjLXJlc2l6ZS1vYnNlcnZlcic7XG5pbXBvcnQgeyBpc0RPTSB9IGZyb20gXCJyYy11dGlsL2VzL0RvbS9maW5kRE9NTm9kZVwiO1xuaW1wb3J0IHVzZUV2ZW50IGZyb20gXCJyYy11dGlsL2VzL2hvb2tzL3VzZUV2ZW50XCI7XG5pbXBvcnQgdXNlSWQgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlSWRcIjtcbmltcG9ydCB1c2VMYXlvdXRFZmZlY3QgZnJvbSBcInJjLXV0aWwvZXMvaG9va3MvdXNlTGF5b3V0RWZmZWN0XCI7XG5pbXBvcnQgaXNNb2JpbGUgZnJvbSBcInJjLXV0aWwvZXMvaXNNb2JpbGVcIjtcbmltcG9ydCB3YXJuaW5nIGZyb20gXCJyYy11dGlsL2VzL3dhcm5pbmdcIjtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBUcmlnZ2VyQ29udGV4dCBmcm9tIFwiLi9jb250ZXh0XCI7XG5pbXBvcnQgdXNlQWN0aW9uIGZyb20gXCIuL2hvb2tzL3VzZUFjdGlvblwiO1xuaW1wb3J0IHVzZUFsaWduIGZyb20gXCIuL2hvb2tzL3VzZUFsaWduXCI7XG5pbXBvcnQgdXNlV2F0Y2ggZnJvbSBcIi4vaG9va3MvdXNlV2F0Y2hcIjtcbmltcG9ydCBQb3B1cCBmcm9tIFwiLi9Qb3B1cFwiO1xuaW1wb3J0IFRyaWdnZXJXcmFwcGVyIGZyb20gXCIuL1RyaWdnZXJXcmFwcGVyXCI7XG5pbXBvcnQgeyBnZXRBbGlnblBvcHVwQ2xhc3NOYW1lLCBnZXRNb3Rpb24sIGdldFdpbiB9IGZyb20gXCIuL3V0aWxcIjtcbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVRyaWdnZXIoKSB7XG4gIHZhciBQb3J0YWxDb21wb25lbnQgPSBhcmd1bWVudHMubGVuZ3RoID4gMCAmJiBhcmd1bWVudHNbMF0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1swXSA6IFBvcnRhbDtcbiAgdmFyIFRyaWdnZXIgPSAvKiNfX1BVUkVfXyovUmVhY3QuZm9yd2FyZFJlZihmdW5jdGlvbiAocHJvcHMsIHJlZikge1xuICAgIHZhciBfcHJvcHMkcHJlZml4Q2xzID0gcHJvcHMucHJlZml4Q2xzLFxuICAgICAgcHJlZml4Q2xzID0gX3Byb3BzJHByZWZpeENscyA9PT0gdm9pZCAwID8gJ3JjLXRyaWdnZXItcG9wdXAnIDogX3Byb3BzJHByZWZpeENscyxcbiAgICAgIGNoaWxkcmVuID0gcHJvcHMuY2hpbGRyZW4sXG4gICAgICBfcHJvcHMkYWN0aW9uID0gcHJvcHMuYWN0aW9uLFxuICAgICAgYWN0aW9uID0gX3Byb3BzJGFjdGlvbiA9PT0gdm9pZCAwID8gJ2hvdmVyJyA6IF9wcm9wcyRhY3Rpb24sXG4gICAgICBzaG93QWN0aW9uID0gcHJvcHMuc2hvd0FjdGlvbixcbiAgICAgIGhpZGVBY3Rpb24gPSBwcm9wcy5oaWRlQWN0aW9uLFxuICAgICAgcG9wdXBWaXNpYmxlID0gcHJvcHMucG9wdXBWaXNpYmxlLFxuICAgICAgZGVmYXVsdFBvcHVwVmlzaWJsZSA9IHByb3BzLmRlZmF1bHRQb3B1cFZpc2libGUsXG4gICAgICBvblBvcHVwVmlzaWJsZUNoYW5nZSA9IHByb3BzLm9uUG9wdXBWaXNpYmxlQ2hhbmdlLFxuICAgICAgYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2UgPSBwcm9wcy5hZnRlclBvcHVwVmlzaWJsZUNoYW5nZSxcbiAgICAgIG1vdXNlRW50ZXJEZWxheSA9IHByb3BzLm1vdXNlRW50ZXJEZWxheSxcbiAgICAgIF9wcm9wcyRtb3VzZUxlYXZlRGVsYSA9IHByb3BzLm1vdXNlTGVhdmVEZWxheSxcbiAgICAgIG1vdXNlTGVhdmVEZWxheSA9IF9wcm9wcyRtb3VzZUxlYXZlRGVsYSA9PT0gdm9pZCAwID8gMC4xIDogX3Byb3BzJG1vdXNlTGVhdmVEZWxhLFxuICAgICAgZm9jdXNEZWxheSA9IHByb3BzLmZvY3VzRGVsYXksXG4gICAgICBibHVyRGVsYXkgPSBwcm9wcy5ibHVyRGVsYXksXG4gICAgICBtYXNrID0gcHJvcHMubWFzayxcbiAgICAgIF9wcm9wcyRtYXNrQ2xvc2FibGUgPSBwcm9wcy5tYXNrQ2xvc2FibGUsXG4gICAgICBtYXNrQ2xvc2FibGUgPSBfcHJvcHMkbWFza0Nsb3NhYmxlID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJG1hc2tDbG9zYWJsZSxcbiAgICAgIGdldFBvcHVwQ29udGFpbmVyID0gcHJvcHMuZ2V0UG9wdXBDb250YWluZXIsXG4gICAgICBmb3JjZVJlbmRlciA9IHByb3BzLmZvcmNlUmVuZGVyLFxuICAgICAgYXV0b0Rlc3Ryb3kgPSBwcm9wcy5hdXRvRGVzdHJveSxcbiAgICAgIGRlc3Ryb3lQb3B1cE9uSGlkZSA9IHByb3BzLmRlc3Ryb3lQb3B1cE9uSGlkZSxcbiAgICAgIHBvcHVwID0gcHJvcHMucG9wdXAsXG4gICAgICBwb3B1cENsYXNzTmFtZSA9IHByb3BzLnBvcHVwQ2xhc3NOYW1lLFxuICAgICAgcG9wdXBTdHlsZSA9IHByb3BzLnBvcHVwU3R5bGUsXG4gICAgICBwb3B1cFBsYWNlbWVudCA9IHByb3BzLnBvcHVwUGxhY2VtZW50LFxuICAgICAgX3Byb3BzJGJ1aWx0aW5QbGFjZW1lID0gcHJvcHMuYnVpbHRpblBsYWNlbWVudHMsXG4gICAgICBidWlsdGluUGxhY2VtZW50cyA9IF9wcm9wcyRidWlsdGluUGxhY2VtZSA9PT0gdm9pZCAwID8ge30gOiBfcHJvcHMkYnVpbHRpblBsYWNlbWUsXG4gICAgICBwb3B1cEFsaWduID0gcHJvcHMucG9wdXBBbGlnbixcbiAgICAgIHpJbmRleCA9IHByb3BzLnpJbmRleCxcbiAgICAgIHN0cmV0Y2ggPSBwcm9wcy5zdHJldGNoLFxuICAgICAgZ2V0UG9wdXBDbGFzc05hbWVGcm9tQWxpZ24gPSBwcm9wcy5nZXRQb3B1cENsYXNzTmFtZUZyb21BbGlnbixcbiAgICAgIGFsaWduUG9pbnQgPSBwcm9wcy5hbGlnblBvaW50LFxuICAgICAgb25Qb3B1cENsaWNrID0gcHJvcHMub25Qb3B1cENsaWNrLFxuICAgICAgb25Qb3B1cEFsaWduID0gcHJvcHMub25Qb3B1cEFsaWduLFxuICAgICAgYXJyb3cgPSBwcm9wcy5hcnJvdyxcbiAgICAgIHBvcHVwTW90aW9uID0gcHJvcHMucG9wdXBNb3Rpb24sXG4gICAgICBtYXNrTW90aW9uID0gcHJvcHMubWFza01vdGlvbixcbiAgICAgIHBvcHVwVHJhbnNpdGlvbk5hbWUgPSBwcm9wcy5wb3B1cFRyYW5zaXRpb25OYW1lLFxuICAgICAgcG9wdXBBbmltYXRpb24gPSBwcm9wcy5wb3B1cEFuaW1hdGlvbixcbiAgICAgIG1hc2tUcmFuc2l0aW9uTmFtZSA9IHByb3BzLm1hc2tUcmFuc2l0aW9uTmFtZSxcbiAgICAgIG1hc2tBbmltYXRpb24gPSBwcm9wcy5tYXNrQW5pbWF0aW9uLFxuICAgICAgY2xhc3NOYW1lID0gcHJvcHMuY2xhc3NOYW1lLFxuICAgICAgZ2V0VHJpZ2dlckRPTU5vZGUgPSBwcm9wcy5nZXRUcmlnZ2VyRE9NTm9kZSxcbiAgICAgIHJlc3RQcm9wcyA9IF9vYmplY3RXaXRob3V0UHJvcGVydGllcyhwcm9wcywgX2V4Y2x1ZGVkKTtcbiAgICB2YXIgbWVyZ2VkQXV0b0Rlc3Ryb3kgPSBhdXRvRGVzdHJveSB8fCBkZXN0cm95UG9wdXBPbkhpZGUgfHwgZmFsc2U7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gTW9iaWxlID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBfUmVhY3QkdXNlU3RhdGUgPSBSZWFjdC51c2VTdGF0ZShmYWxzZSksXG4gICAgICBfUmVhY3QkdXNlU3RhdGUyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlLCAyKSxcbiAgICAgIG1vYmlsZSA9IF9SZWFjdCR1c2VTdGF0ZTJbMF0sXG4gICAgICBzZXRNb2JpbGUgPSBfUmVhY3QkdXNlU3RhdGUyWzFdO1xuICAgIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICBzZXRNb2JpbGUoaXNNb2JpbGUoKSk7XG4gICAgfSwgW10pO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gQ29udGV4dCA9PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgc3ViUG9wdXBFbGVtZW50cyA9IFJlYWN0LnVzZVJlZih7fSk7XG4gICAgdmFyIHBhcmVudENvbnRleHQgPSBSZWFjdC51c2VDb250ZXh0KFRyaWdnZXJDb250ZXh0KTtcbiAgICB2YXIgY29udGV4dCA9IFJlYWN0LnVzZU1lbW8oZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVnaXN0ZXJTdWJQb3B1cDogZnVuY3Rpb24gcmVnaXN0ZXJTdWJQb3B1cChpZCwgc3ViUG9wdXBFbGUpIHtcbiAgICAgICAgICBzdWJQb3B1cEVsZW1lbnRzLmN1cnJlbnRbaWRdID0gc3ViUG9wdXBFbGU7XG4gICAgICAgICAgcGFyZW50Q29udGV4dCA9PT0gbnVsbCB8fCBwYXJlbnRDb250ZXh0ID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwYXJlbnRDb250ZXh0LnJlZ2lzdGVyU3ViUG9wdXAoaWQsIHN1YlBvcHVwRWxlKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9LCBbcGFyZW50Q29udGV4dF0pO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09IFBvcHVwID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgaWQgPSB1c2VJZCgpO1xuICAgIHZhciBfUmVhY3QkdXNlU3RhdGUzID0gUmVhY3QudXNlU3RhdGUobnVsbCksXG4gICAgICBfUmVhY3QkdXNlU3RhdGU0ID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMywgMiksXG4gICAgICBwb3B1cEVsZSA9IF9SZWFjdCR1c2VTdGF0ZTRbMF0sXG4gICAgICBzZXRQb3B1cEVsZSA9IF9SZWFjdCR1c2VTdGF0ZTRbMV07XG4gICAgdmFyIHNldFBvcHVwUmVmID0gdXNlRXZlbnQoZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgIGlmIChpc0RPTShub2RlKSAmJiBwb3B1cEVsZSAhPT0gbm9kZSkge1xuICAgICAgICBzZXRQb3B1cEVsZShub2RlKTtcbiAgICAgIH1cbiAgICAgIHBhcmVudENvbnRleHQgPT09IG51bGwgfHwgcGFyZW50Q29udGV4dCA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyZW50Q29udGV4dC5yZWdpc3RlclN1YlBvcHVwKGlkLCBub2RlKTtcbiAgICB9KTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBUYXJnZXQgPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gVXNlIHN0YXRlIHRvIGNvbnRyb2wgaGVyZSBzaW5jZSBgdXNlUmVmYCB1cGRhdGUgbm90IHRyaWdnZXIgcmVuZGVyXG4gICAgdmFyIF9SZWFjdCR1c2VTdGF0ZTUgPSBSZWFjdC51c2VTdGF0ZShudWxsKSxcbiAgICAgIF9SZWFjdCR1c2VTdGF0ZTYgPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGU1LCAyKSxcbiAgICAgIHRhcmdldEVsZSA9IF9SZWFjdCR1c2VTdGF0ZTZbMF0sXG4gICAgICBzZXRUYXJnZXRFbGUgPSBfUmVhY3QkdXNlU3RhdGU2WzFdO1xuICAgIHZhciBzZXRUYXJnZXRSZWYgPSB1c2VFdmVudChmdW5jdGlvbiAobm9kZSkge1xuICAgICAgaWYgKGlzRE9NKG5vZGUpICYmIHRhcmdldEVsZSAhPT0gbm9kZSkge1xuICAgICAgICBzZXRUYXJnZXRFbGUobm9kZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PSBDaGlsZHJlbiA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBjaGlsZCA9IFJlYWN0LkNoaWxkcmVuLm9ubHkoY2hpbGRyZW4pO1xuICAgIHZhciBvcmlnaW5DaGlsZFByb3BzID0gKGNoaWxkID09PSBudWxsIHx8IGNoaWxkID09PSB2b2lkIDAgPyB2b2lkIDAgOiBjaGlsZC5wcm9wcykgfHwge307XG4gICAgdmFyIGNsb25lUHJvcHMgPSB7fTtcbiAgICB2YXIgaW5Qb3B1cE9yQ2hpbGQgPSB1c2VFdmVudChmdW5jdGlvbiAoZWxlKSB7XG4gICAgICB2YXIgX2NoaWxkRE9NJGdldFJvb3ROb2RlLCBfcG9wdXBFbGUkZ2V0Um9vdE5vZGU7XG4gICAgICB2YXIgY2hpbGRET00gPSB0YXJnZXRFbGU7XG4gICAgICByZXR1cm4gKGNoaWxkRE9NID09PSBudWxsIHx8IGNoaWxkRE9NID09PSB2b2lkIDAgPyB2b2lkIDAgOiBjaGlsZERPTS5jb250YWlucyhlbGUpKSB8fCAoY2hpbGRET00gPT09IG51bGwgfHwgY2hpbGRET00gPT09IHZvaWQgMCA/IHZvaWQgMCA6IChfY2hpbGRET00kZ2V0Um9vdE5vZGUgPSBjaGlsZERPTS5nZXRSb290Tm9kZSgpKSA9PT0gbnVsbCB8fCBfY2hpbGRET00kZ2V0Um9vdE5vZGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9jaGlsZERPTSRnZXRSb290Tm9kZS5ob3N0KSA9PT0gZWxlIHx8IGVsZSA9PT0gY2hpbGRET00gfHwgKHBvcHVwRWxlID09PSBudWxsIHx8IHBvcHVwRWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBwb3B1cEVsZS5jb250YWlucyhlbGUpKSB8fCAocG9wdXBFbGUgPT09IG51bGwgfHwgcG9wdXBFbGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IChfcG9wdXBFbGUkZ2V0Um9vdE5vZGUgPSBwb3B1cEVsZS5nZXRSb290Tm9kZSgpKSA9PT0gbnVsbCB8fCBfcG9wdXBFbGUkZ2V0Um9vdE5vZGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9wb3B1cEVsZSRnZXRSb290Tm9kZS5ob3N0KSA9PT0gZWxlIHx8IGVsZSA9PT0gcG9wdXBFbGUgfHwgT2JqZWN0LnZhbHVlcyhzdWJQb3B1cEVsZW1lbnRzLmN1cnJlbnQpLnNvbWUoZnVuY3Rpb24gKHN1YlBvcHVwRWxlKSB7XG4gICAgICAgIHJldHVybiAoc3ViUG9wdXBFbGUgPT09IG51bGwgfHwgc3ViUG9wdXBFbGUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHN1YlBvcHVwRWxlLmNvbnRhaW5zKGVsZSkpIHx8IGVsZSA9PT0gc3ViUG9wdXBFbGU7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBNb3Rpb24gPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIG1lcmdlUG9wdXBNb3Rpb24gPSBnZXRNb3Rpb24ocHJlZml4Q2xzLCBwb3B1cE1vdGlvbiwgcG9wdXBBbmltYXRpb24sIHBvcHVwVHJhbnNpdGlvbk5hbWUpO1xuICAgIHZhciBtZXJnZU1hc2tNb3Rpb24gPSBnZXRNb3Rpb24ocHJlZml4Q2xzLCBtYXNrTW90aW9uLCBtYXNrQW5pbWF0aW9uLCBtYXNrVHJhbnNpdGlvbk5hbWUpO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PSBPcGVuID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlNyA9IFJlYWN0LnVzZVN0YXRlKGRlZmF1bHRQb3B1cFZpc2libGUgfHwgZmFsc2UpLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlOCA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTcsIDIpLFxuICAgICAgaW50ZXJuYWxPcGVuID0gX1JlYWN0JHVzZVN0YXRlOFswXSxcbiAgICAgIHNldEludGVybmFsT3BlbiA9IF9SZWFjdCR1c2VTdGF0ZThbMV07XG5cbiAgICAvLyBSZW5kZXIgc3RpbGwgdXNlIHByb3BzIGFzIGZpcnN0IHByaW9yaXR5XG4gICAgdmFyIG1lcmdlZE9wZW4gPSBwb3B1cFZpc2libGUgIT09IG51bGwgJiYgcG9wdXBWaXNpYmxlICE9PSB2b2lkIDAgPyBwb3B1cFZpc2libGUgOiBpbnRlcm5hbE9wZW47XG5cbiAgICAvLyBXZSB1c2UgZWZmZWN0IHN5bmMgaGVyZSBpbiBjYXNlIGBwb3B1cFZpc2libGVgIGJhY2sgdG8gYHVuZGVmaW5lZGBcbiAgICB2YXIgc2V0TWVyZ2VkT3BlbiA9IHVzZUV2ZW50KGZ1bmN0aW9uIChuZXh0T3Blbikge1xuICAgICAgaWYgKHBvcHVwVmlzaWJsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNldEludGVybmFsT3BlbihuZXh0T3Blbik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHNldEludGVybmFsT3Blbihwb3B1cFZpc2libGUgfHwgZmFsc2UpO1xuICAgIH0sIFtwb3B1cFZpc2libGVdKTtcbiAgICB2YXIgb3BlblJlZiA9IFJlYWN0LnVzZVJlZihtZXJnZWRPcGVuKTtcbiAgICBvcGVuUmVmLmN1cnJlbnQgPSBtZXJnZWRPcGVuO1xuICAgIHZhciBpbnRlcm5hbFRyaWdnZXJPcGVuID0gdXNlRXZlbnQoZnVuY3Rpb24gKG5leHRPcGVuKSB7XG4gICAgICBpZiAobWVyZ2VkT3BlbiAhPT0gbmV4dE9wZW4pIHtcbiAgICAgICAgc2V0TWVyZ2VkT3BlbihuZXh0T3Blbik7XG4gICAgICAgIG9uUG9wdXBWaXNpYmxlQ2hhbmdlID09PSBudWxsIHx8IG9uUG9wdXBWaXNpYmxlQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvblBvcHVwVmlzaWJsZUNoYW5nZShuZXh0T3Blbik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBUcmlnZ2VyIGZvciBkZWxheVxuICAgIHZhciBkZWxheVJlZiA9IFJlYWN0LnVzZVJlZigpO1xuICAgIHZhciBjbGVhckRlbGF5ID0gZnVuY3Rpb24gY2xlYXJEZWxheSgpIHtcbiAgICAgIGNsZWFyVGltZW91dChkZWxheVJlZi5jdXJyZW50KTtcbiAgICB9O1xuICAgIHZhciB0cmlnZ2VyT3BlbiA9IGZ1bmN0aW9uIHRyaWdnZXJPcGVuKG5leHRPcGVuKSB7XG4gICAgICB2YXIgZGVsYXkgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IDA7XG4gICAgICBjbGVhckRlbGF5KCk7XG4gICAgICBpZiAoZGVsYXkgPT09IDApIHtcbiAgICAgICAgaW50ZXJuYWxUcmlnZ2VyT3BlbihuZXh0T3Blbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxheVJlZi5jdXJyZW50ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaW50ZXJuYWxUcmlnZ2VyT3BlbihuZXh0T3Blbik7XG4gICAgICAgIH0sIGRlbGF5ICogMTAwMCk7XG4gICAgICB9XG4gICAgfTtcbiAgICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGNsZWFyRGVsYXk7XG4gICAgfSwgW10pO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT0gTW90aW9uID09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlOSA9IFJlYWN0LnVzZVN0YXRlKGZhbHNlKSxcbiAgICAgIF9SZWFjdCR1c2VTdGF0ZTEwID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlOSwgMiksXG4gICAgICBpbk1vdGlvbiA9IF9SZWFjdCR1c2VTdGF0ZTEwWzBdLFxuICAgICAgc2V0SW5Nb3Rpb24gPSBfUmVhY3QkdXNlU3RhdGUxMFsxXTtcbiAgICB2YXIgbW91bnRSZWYgPSBSZWFjdC51c2VSZWYodHJ1ZSk7XG4gICAgdXNlTGF5b3V0RWZmZWN0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICghbW91bnRSZWYuY3VycmVudCB8fCBtZXJnZWRPcGVuKSB7XG4gICAgICAgIHNldEluTW90aW9uKHRydWUpO1xuICAgICAgfVxuICAgICAgbW91bnRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgfSwgW21lcmdlZE9wZW5dKTtcbiAgICB2YXIgX1JlYWN0JHVzZVN0YXRlMTEgPSBSZWFjdC51c2VTdGF0ZShudWxsKSxcbiAgICAgIF9SZWFjdCR1c2VTdGF0ZTEyID0gX3NsaWNlZFRvQXJyYXkoX1JlYWN0JHVzZVN0YXRlMTEsIDIpLFxuICAgICAgbW90aW9uUHJlcGFyZVJlc29sdmUgPSBfUmVhY3QkdXNlU3RhdGUxMlswXSxcbiAgICAgIHNldE1vdGlvblByZXBhcmVSZXNvbHZlID0gX1JlYWN0JHVzZVN0YXRlMTJbMV07XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gQWxpZ24gPT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBfUmVhY3QkdXNlU3RhdGUxMyA9IFJlYWN0LnVzZVN0YXRlKFswLCAwXSksXG4gICAgICBfUmVhY3QkdXNlU3RhdGUxNCA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTEzLCAyKSxcbiAgICAgIG1vdXNlUG9zID0gX1JlYWN0JHVzZVN0YXRlMTRbMF0sXG4gICAgICBzZXRNb3VzZVBvcyA9IF9SZWFjdCR1c2VTdGF0ZTE0WzFdO1xuICAgIHZhciBzZXRNb3VzZVBvc0J5RXZlbnQgPSBmdW5jdGlvbiBzZXRNb3VzZVBvc0J5RXZlbnQoZXZlbnQpIHtcbiAgICAgIHNldE1vdXNlUG9zKFtldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZXSk7XG4gICAgfTtcbiAgICB2YXIgX3VzZUFsaWduID0gdXNlQWxpZ24obWVyZ2VkT3BlbiwgcG9wdXBFbGUsIGFsaWduUG9pbnQgPyBtb3VzZVBvcyA6IHRhcmdldEVsZSwgcG9wdXBQbGFjZW1lbnQsIGJ1aWx0aW5QbGFjZW1lbnRzLCBwb3B1cEFsaWduLCBvblBvcHVwQWxpZ24pLFxuICAgICAgX3VzZUFsaWduMiA9IF9zbGljZWRUb0FycmF5KF91c2VBbGlnbiwgOSksXG4gICAgICByZWFkeSA9IF91c2VBbGlnbjJbMF0sXG4gICAgICBvZmZzZXRYID0gX3VzZUFsaWduMlsxXSxcbiAgICAgIG9mZnNldFkgPSBfdXNlQWxpZ24yWzJdLFxuICAgICAgYXJyb3dYID0gX3VzZUFsaWduMlszXSxcbiAgICAgIGFycm93WSA9IF91c2VBbGlnbjJbNF0sXG4gICAgICBzY2FsZVggPSBfdXNlQWxpZ24yWzVdLFxuICAgICAgc2NhbGVZID0gX3VzZUFsaWduMls2XSxcbiAgICAgIGFsaWduSW5mbyA9IF91c2VBbGlnbjJbN10sXG4gICAgICBvbkFsaWduID0gX3VzZUFsaWduMls4XTtcbiAgICB2YXIgdHJpZ2dlckFsaWduID0gdXNlRXZlbnQoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKCFpbk1vdGlvbikge1xuICAgICAgICBvbkFsaWduKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdXNlV2F0Y2gobWVyZ2VkT3BlbiwgdGFyZ2V0RWxlLCBwb3B1cEVsZSwgdHJpZ2dlckFsaWduKTtcbiAgICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgdHJpZ2dlckFsaWduKCk7XG4gICAgfSwgW21vdXNlUG9zXSk7XG5cbiAgICAvLyBXaGVuIG5vIGJ1aWx0aW5QbGFjZW1lbnRzIGFuZCBwb3B1cEFsaWduIGNoYW5nZWRcbiAgICB1c2VMYXlvdXRFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKG1lcmdlZE9wZW4gJiYgIShidWlsdGluUGxhY2VtZW50cyAhPT0gbnVsbCAmJiBidWlsdGluUGxhY2VtZW50cyAhPT0gdm9pZCAwICYmIGJ1aWx0aW5QbGFjZW1lbnRzW3BvcHVwUGxhY2VtZW50XSkpIHtcbiAgICAgICAgdHJpZ2dlckFsaWduKCk7XG4gICAgICB9XG4gICAgfSwgW0pTT04uc3RyaW5naWZ5KHBvcHVwQWxpZ24pXSk7XG4gICAgdmFyIGFsaWduZWRDbGFzc05hbWUgPSBSZWFjdC51c2VNZW1vKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBiYXNlQ2xhc3NOYW1lID0gZ2V0QWxpZ25Qb3B1cENsYXNzTmFtZShidWlsdGluUGxhY2VtZW50cywgcHJlZml4Q2xzLCBhbGlnbkluZm8sIGFsaWduUG9pbnQpO1xuICAgICAgcmV0dXJuIGNsYXNzTmFtZXMoYmFzZUNsYXNzTmFtZSwgZ2V0UG9wdXBDbGFzc05hbWVGcm9tQWxpZ24gPT09IG51bGwgfHwgZ2V0UG9wdXBDbGFzc05hbWVGcm9tQWxpZ24gPT09IHZvaWQgMCA/IHZvaWQgMCA6IGdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduKGFsaWduSW5mbykpO1xuICAgIH0sIFthbGlnbkluZm8sIGdldFBvcHVwQ2xhc3NOYW1lRnJvbUFsaWduLCBidWlsdGluUGxhY2VtZW50cywgcHJlZml4Q2xzLCBhbGlnblBvaW50XSk7XG4gICAgUmVhY3QudXNlSW1wZXJhdGl2ZUhhbmRsZShyZWYsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZvcmNlQWxpZ246IHRyaWdnZXJBbGlnblxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IE1vdGlvbiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIG9uVmlzaWJsZUNoYW5nZWQgPSBmdW5jdGlvbiBvblZpc2libGVDaGFuZ2VkKHZpc2libGUpIHtcbiAgICAgIHNldEluTW90aW9uKGZhbHNlKTtcbiAgICAgIG9uQWxpZ24oKTtcbiAgICAgIGFmdGVyUG9wdXBWaXNpYmxlQ2hhbmdlID09PSBudWxsIHx8IGFmdGVyUG9wdXBWaXNpYmxlQ2hhbmdlID09PSB2b2lkIDAgPyB2b2lkIDAgOiBhZnRlclBvcHVwVmlzaWJsZUNoYW5nZSh2aXNpYmxlKTtcbiAgICB9O1xuXG4gICAgLy8gV2Ugd2lsbCB0cmlnZ2VyIGFsaWduIHdoZW4gbW90aW9uIGlzIGluIHByZXBhcmVcbiAgICB2YXIgb25QcmVwYXJlID0gZnVuY3Rpb24gb25QcmVwYXJlKCkge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgICAgIHNldE1vdGlvblByZXBhcmVSZXNvbHZlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICByZXR1cm4gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHVzZUxheW91dEVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAobW90aW9uUHJlcGFyZVJlc29sdmUpIHtcbiAgICAgICAgb25BbGlnbigpO1xuICAgICAgICBtb3Rpb25QcmVwYXJlUmVzb2x2ZSgpO1xuICAgICAgICBzZXRNb3Rpb25QcmVwYXJlUmVzb2x2ZShudWxsKTtcbiAgICAgIH1cbiAgICB9LCBbbW90aW9uUHJlcGFyZVJlc29sdmVdKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09IFN0cmV0Y2ggPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIF9SZWFjdCR1c2VTdGF0ZTE1ID0gUmVhY3QudXNlU3RhdGUoMCksXG4gICAgICBfUmVhY3QkdXNlU3RhdGUxNiA9IF9zbGljZWRUb0FycmF5KF9SZWFjdCR1c2VTdGF0ZTE1LCAyKSxcbiAgICAgIHRhcmdldFdpZHRoID0gX1JlYWN0JHVzZVN0YXRlMTZbMF0sXG4gICAgICBzZXRUYXJnZXRXaWR0aCA9IF9SZWFjdCR1c2VTdGF0ZTE2WzFdO1xuICAgIHZhciBfUmVhY3QkdXNlU3RhdGUxNyA9IFJlYWN0LnVzZVN0YXRlKDApLFxuICAgICAgX1JlYWN0JHVzZVN0YXRlMTggPSBfc2xpY2VkVG9BcnJheShfUmVhY3QkdXNlU3RhdGUxNywgMiksXG4gICAgICB0YXJnZXRIZWlnaHQgPSBfUmVhY3QkdXNlU3RhdGUxOFswXSxcbiAgICAgIHNldFRhcmdldEhlaWdodCA9IF9SZWFjdCR1c2VTdGF0ZTE4WzFdO1xuICAgIHZhciBvblRhcmdldFJlc2l6ZSA9IGZ1bmN0aW9uIG9uVGFyZ2V0UmVzaXplKF8sIGVsZSkge1xuICAgICAgdHJpZ2dlckFsaWduKCk7XG4gICAgICBpZiAoc3RyZXRjaCkge1xuICAgICAgICB2YXIgcmVjdCA9IGVsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgc2V0VGFyZ2V0V2lkdGgocmVjdC53aWR0aCk7XG4gICAgICAgIHNldFRhcmdldEhlaWdodChyZWN0LmhlaWdodCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PSBBY3Rpb24gPT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgdmFyIF91c2VBY3Rpb24gPSB1c2VBY3Rpb24obW9iaWxlLCBhY3Rpb24sIHNob3dBY3Rpb24sIGhpZGVBY3Rpb24pLFxuICAgICAgX3VzZUFjdGlvbjIgPSBfc2xpY2VkVG9BcnJheShfdXNlQWN0aW9uLCAyKSxcbiAgICAgIHNob3dBY3Rpb25zID0gX3VzZUFjdGlvbjJbMF0sXG4gICAgICBoaWRlQWN0aW9ucyA9IF91c2VBY3Rpb24yWzFdO1xuXG4gICAgLy8gVXRpbCB3cmFwcGVyIGZvciB0cmlnZ2VyIGFjdGlvblxuICAgIHZhciB3cmFwcGVyQWN0aW9uID0gZnVuY3Rpb24gd3JhcHBlckFjdGlvbihldmVudE5hbWUsIG5leHRPcGVuLCBkZWxheSwgcHJlRXZlbnQpIHtcbiAgICAgIGNsb25lUHJvcHNbZXZlbnROYW1lXSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB2YXIgX29yaWdpbkNoaWxkUHJvcHMkZXZlO1xuICAgICAgICBwcmVFdmVudCA9PT0gbnVsbCB8fCBwcmVFdmVudCA9PT0gdm9pZCAwID8gdm9pZCAwIDogcHJlRXZlbnQoZXZlbnQpO1xuICAgICAgICB0cmlnZ2VyT3BlbihuZXh0T3BlbiwgZGVsYXkpO1xuXG4gICAgICAgIC8vIFBhc3MgdG8gb3JpZ2luXG4gICAgICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgICBhcmdzW19rZXkgLSAxXSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgICAgICAgfVxuICAgICAgICAoX29yaWdpbkNoaWxkUHJvcHMkZXZlID0gb3JpZ2luQ2hpbGRQcm9wc1tldmVudE5hbWVdKSA9PT0gbnVsbCB8fCBfb3JpZ2luQ2hpbGRQcm9wcyRldmUgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9vcmlnaW5DaGlsZFByb3BzJGV2ZS5jYWxsLmFwcGx5KF9vcmlnaW5DaGlsZFByb3BzJGV2ZSwgW29yaWdpbkNoaWxkUHJvcHMsIGV2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT0gQWN0aW9uOiBDbGljayA9PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgY2xpY2tUb1Nob3cgPSBzaG93QWN0aW9ucy5oYXMoJ2NsaWNrJyk7XG4gICAgdmFyIGNsaWNrVG9IaWRlID0gaGlkZUFjdGlvbnMuaGFzKCdjbGljaycpIHx8IGhpZGVBY3Rpb25zLmhhcygnY29udGV4dE1lbnUnKTtcbiAgICBpZiAoY2xpY2tUb1Nob3cgfHwgY2xpY2tUb0hpZGUpIHtcbiAgICAgIGNsb25lUHJvcHMub25DbGljayA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB2YXIgX29yaWdpbkNoaWxkUHJvcHMkb25DO1xuICAgICAgICBpZiAob3BlblJlZi5jdXJyZW50ICYmIGNsaWNrVG9IaWRlKSB7XG4gICAgICAgICAgdHJpZ2dlck9wZW4oZmFsc2UpO1xuICAgICAgICB9IGVsc2UgaWYgKCFvcGVuUmVmLmN1cnJlbnQgJiYgY2xpY2tUb1Nob3cpIHtcbiAgICAgICAgICBzZXRNb3VzZVBvc0J5RXZlbnQoZXZlbnQpO1xuICAgICAgICAgIHRyaWdnZXJPcGVuKHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGFzcyB0byBvcmlnaW5cbiAgICAgICAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4yID4gMSA/IF9sZW4yIC0gMSA6IDApLCBfa2V5MiA9IDE7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgICAgICBhcmdzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICAgICAgICB9XG4gICAgICAgIChfb3JpZ2luQ2hpbGRQcm9wcyRvbkMgPSBvcmlnaW5DaGlsZFByb3BzLm9uQ2xpY2spID09PSBudWxsIHx8IF9vcmlnaW5DaGlsZFByb3BzJG9uQyA9PT0gdm9pZCAwID8gdm9pZCAwIDogX29yaWdpbkNoaWxkUHJvcHMkb25DLmNhbGwuYXBwbHkoX29yaWdpbkNoaWxkUHJvcHMkb25DLCBbb3JpZ2luQ2hpbGRQcm9wcywgZXZlbnRdLmNvbmNhdChhcmdzKSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIENsaWNrIHRvIGhpZGUgaXMgc3BlY2lhbCBhY3Rpb24gc2luY2UgY2xpY2sgcG9wdXAgZWxlbWVudCBzaG91bGQgbm90IGhpZGVcbiAgICBSZWFjdC51c2VFZmZlY3QoZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGNsaWNrVG9IaWRlICYmIHBvcHVwRWxlICYmICghbWFzayB8fCBtYXNrQ2xvc2FibGUpKSB7XG4gICAgICAgIHZhciBjbGlja0luc2lkZSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIFVzZXIgbWF5IG1vdXNlRG93biBpbnNpZGUgYW5kIGRyYWcgb3V0IG9mIHBvcHVwIGFuZCBtb3VzZSB1cFxuICAgICAgICAvLyBSZWNvcmQgaGVyZSB0byBwcmV2ZW50IGNsb3NlXG4gICAgICAgIHZhciBvbldpbmRvd01vdXNlRG93biA9IGZ1bmN0aW9uIG9uV2luZG93TW91c2VEb3duKF9yZWYpIHtcbiAgICAgICAgICB2YXIgdGFyZ2V0ID0gX3JlZi50YXJnZXQ7XG4gICAgICAgICAgY2xpY2tJbnNpZGUgPSBpblBvcHVwT3JDaGlsZCh0YXJnZXQpO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgb25XaW5kb3dDbGljayA9IGZ1bmN0aW9uIG9uV2luZG93Q2xpY2soX3JlZjIpIHtcbiAgICAgICAgICB2YXIgdGFyZ2V0ID0gX3JlZjIudGFyZ2V0O1xuICAgICAgICAgIGlmIChvcGVuUmVmLmN1cnJlbnQgJiYgIWNsaWNrSW5zaWRlICYmICFpblBvcHVwT3JDaGlsZCh0YXJnZXQpKSB7XG4gICAgICAgICAgICB0cmlnZ2VyT3BlbihmYWxzZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2YXIgd2luID0gZ2V0V2luKHBvcHVwRWxlKTtcbiAgICAgICAgdmFyIHRhcmdldFJvb3QgPSB0YXJnZXRFbGUgPT09IG51bGwgfHwgdGFyZ2V0RWxlID09PSB2b2lkIDAgPyB2b2lkIDAgOiB0YXJnZXRFbGUuZ2V0Um9vdE5vZGUoKTtcbiAgICAgICAgd2luLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uV2luZG93TW91c2VEb3duKTtcbiAgICAgICAgd2luLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgb25XaW5kb3dDbGljayk7XG5cbiAgICAgICAgLy8gc2hhZG93IHJvb3RcbiAgICAgICAgdmFyIGluU2hhZG93ID0gdGFyZ2V0Um9vdCAmJiB0YXJnZXRSb290ICE9PSB0YXJnZXRFbGUub3duZXJEb2N1bWVudDtcbiAgICAgICAgaWYgKGluU2hhZG93KSB7XG4gICAgICAgICAgdGFyZ2V0Um9vdC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCBvbldpbmRvd01vdXNlRG93bik7XG4gICAgICAgICAgdGFyZ2V0Um9vdC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIG9uV2luZG93Q2xpY2spO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gV2FybmluZyBpZiB0YXJnZXQgYW5kIHBvcHVwIG5vdCBpbiBzYW1lIHJvb3RcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAgICAgICB2YXIgcG9wdXBSb290ID0gcG9wdXBFbGUuZ2V0Um9vdE5vZGUoKTtcbiAgICAgICAgICB3YXJuaW5nKHRhcmdldFJvb3QgPT09IHBvcHVwUm9vdCwgXCJ0cmlnZ2VyIGVsZW1lbnQgYW5kIHBvcHVwIGVsZW1lbnQgc2hvdWxkIGluIHNhbWUgc2hhZG93IHJvb3QuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uV2luZG93TW91c2VEb3duKTtcbiAgICAgICAgICB3aW4ucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbldpbmRvd0NsaWNrKTtcbiAgICAgICAgICBpZiAoaW5TaGFkb3cpIHtcbiAgICAgICAgICAgIHRhcmdldFJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25XaW5kb3dNb3VzZURvd24pO1xuICAgICAgICAgICAgdGFyZ2V0Um9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIG9uV2luZG93Q2xpY2spO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9LCBbY2xpY2tUb0hpZGUsIHRhcmdldEVsZSwgcG9wdXBFbGUsIG1hc2ssIG1hc2tDbG9zYWJsZV0pO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT0gQWN0aW9uOiBIb3ZlciA9PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICB2YXIgaG92ZXJUb1Nob3cgPSBzaG93QWN0aW9ucy5oYXMoJ2hvdmVyJyk7XG4gICAgdmFyIGhvdmVyVG9IaWRlID0gaGlkZUFjdGlvbnMuaGFzKCdob3ZlcicpO1xuICAgIHZhciBvblBvcHVwTW91c2VFbnRlcjtcbiAgICB2YXIgb25Qb3B1cE1vdXNlTGVhdmU7XG4gICAgaWYgKGhvdmVyVG9TaG93KSB7XG4gICAgICB3cmFwcGVyQWN0aW9uKCdvbk1vdXNlRW50ZXInLCB0cnVlLCBtb3VzZUVudGVyRGVsYXksIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBzZXRNb3VzZVBvc0J5RXZlbnQoZXZlbnQpO1xuICAgICAgfSk7XG4gICAgICBvblBvcHVwTW91c2VFbnRlciA9IGZ1bmN0aW9uIG9uUG9wdXBNb3VzZUVudGVyKCkge1xuICAgICAgICB0cmlnZ2VyT3Blbih0cnVlLCBtb3VzZUVudGVyRGVsYXkpO1xuICAgICAgfTtcblxuICAgICAgLy8gQWxpZ24gUG9pbnRcbiAgICAgIGlmIChhbGlnblBvaW50KSB7XG4gICAgICAgIGNsb25lUHJvcHMub25Nb3VzZU1vdmUgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICB2YXIgX29yaWdpbkNoaWxkUHJvcHMkb25NO1xuICAgICAgICAgIC8vIHNldE1vdXNlUG9zQnlFdmVudChldmVudCk7XG4gICAgICAgICAgKF9vcmlnaW5DaGlsZFByb3BzJG9uTSA9IG9yaWdpbkNoaWxkUHJvcHMub25Nb3VzZU1vdmUpID09PSBudWxsIHx8IF9vcmlnaW5DaGlsZFByb3BzJG9uTSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX29yaWdpbkNoaWxkUHJvcHMkb25NLmNhbGwob3JpZ2luQ2hpbGRQcm9wcywgZXZlbnQpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaG92ZXJUb0hpZGUpIHtcbiAgICAgIHdyYXBwZXJBY3Rpb24oJ29uTW91c2VMZWF2ZScsIGZhbHNlLCBtb3VzZUxlYXZlRGVsYXkpO1xuICAgICAgb25Qb3B1cE1vdXNlTGVhdmUgPSBmdW5jdGlvbiBvblBvcHVwTW91c2VMZWF2ZSgpIHtcbiAgICAgICAgdHJpZ2dlck9wZW4oZmFsc2UsIG1vdXNlTGVhdmVEZWxheSk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09IEFjdGlvbjogRm9jdXMgPT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgaWYgKHNob3dBY3Rpb25zLmhhcygnZm9jdXMnKSkge1xuICAgICAgd3JhcHBlckFjdGlvbignb25Gb2N1cycsIHRydWUsIGZvY3VzRGVsYXkpO1xuICAgIH1cbiAgICBpZiAoaGlkZUFjdGlvbnMuaGFzKCdmb2N1cycpKSB7XG4gICAgICB3cmFwcGVyQWN0aW9uKCdvbkJsdXInLCBmYWxzZSwgYmx1ckRlbGF5KTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PSBBY3Rpb246IENvbnRleHRNZW51ID09PT09PT09PT09PT09PT09PT09PVxuICAgIGlmIChzaG93QWN0aW9ucy5oYXMoJ2NvbnRleHRNZW51JykpIHtcbiAgICAgIGNsb25lUHJvcHMub25Db250ZXh0TWVudSA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB2YXIgX29yaWdpbkNoaWxkUHJvcHMkb25DMjtcbiAgICAgICAgc2V0TW91c2VQb3NCeUV2ZW50KGV2ZW50KTtcbiAgICAgICAgdHJpZ2dlck9wZW4odHJ1ZSk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gUGFzcyB0byBvcmlnaW5cbiAgICAgICAgZm9yICh2YXIgX2xlbjMgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW4zID4gMSA/IF9sZW4zIC0gMSA6IDApLCBfa2V5MyA9IDE7IF9rZXkzIDwgX2xlbjM7IF9rZXkzKyspIHtcbiAgICAgICAgICBhcmdzW19rZXkzIC0gMV0gPSBhcmd1bWVudHNbX2tleTNdO1xuICAgICAgICB9XG4gICAgICAgIChfb3JpZ2luQ2hpbGRQcm9wcyRvbkMyID0gb3JpZ2luQ2hpbGRQcm9wcy5vbkNvbnRleHRNZW51KSA9PT0gbnVsbCB8fCBfb3JpZ2luQ2hpbGRQcm9wcyRvbkMyID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfb3JpZ2luQ2hpbGRQcm9wcyRvbkMyLmNhbGwuYXBwbHkoX29yaWdpbkNoaWxkUHJvcHMkb25DMiwgW29yaWdpbkNoaWxkUHJvcHMsIGV2ZW50XS5jb25jYXQoYXJncykpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09IENsYXNzTmFtZSA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIGNsb25lUHJvcHMuY2xhc3NOYW1lID0gY2xhc3NOYW1lcyhvcmlnaW5DaGlsZFByb3BzLmNsYXNzTmFtZSwgY2xhc3NOYW1lKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT0gUmVuZGVyID09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIHZhciBtZXJnZWRDaGlsZHJlblByb3BzID0gX29iamVjdFNwcmVhZChfb2JqZWN0U3ByZWFkKHt9LCBvcmlnaW5DaGlsZFByb3BzKSwgY2xvbmVQcm9wcyk7XG5cbiAgICAvLyBQYXNzIHByb3BzIGludG8gY2xvbmVQcm9wcyBmb3IgbmVzdCB1c2FnZVxuICAgIHZhciBwYXNzZWRQcm9wcyA9IHt9O1xuICAgIHZhciBwYXNzZWRFdmVudExpc3QgPSBbJ29uQ29udGV4dE1lbnUnLCAnb25DbGljaycsICdvbk1vdXNlRG93bicsICdvblRvdWNoU3RhcnQnLCAnb25Nb3VzZUVudGVyJywgJ29uTW91c2VMZWF2ZScsICdvbkZvY3VzJywgJ29uQmx1ciddO1xuICAgIHBhc3NlZEV2ZW50TGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChldmVudE5hbWUpIHtcbiAgICAgIGlmIChyZXN0UHJvcHNbZXZlbnROYW1lXSkge1xuICAgICAgICBwYXNzZWRQcm9wc1tldmVudE5hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBfbWVyZ2VkQ2hpbGRyZW5Qcm9wcyQ7XG4gICAgICAgICAgZm9yICh2YXIgX2xlbjQgPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KF9sZW40KSwgX2tleTQgPSAwOyBfa2V5NCA8IF9sZW40OyBfa2V5NCsrKSB7XG4gICAgICAgICAgICBhcmdzW19rZXk0XSA9IGFyZ3VtZW50c1tfa2V5NF07XG4gICAgICAgICAgfVxuICAgICAgICAgIChfbWVyZ2VkQ2hpbGRyZW5Qcm9wcyQgPSBtZXJnZWRDaGlsZHJlblByb3BzW2V2ZW50TmFtZV0pID09PSBudWxsIHx8IF9tZXJnZWRDaGlsZHJlblByb3BzJCA9PT0gdm9pZCAwID8gdm9pZCAwIDogX21lcmdlZENoaWxkcmVuUHJvcHMkLmNhbGwuYXBwbHkoX21lcmdlZENoaWxkcmVuUHJvcHMkLCBbbWVyZ2VkQ2hpbGRyZW5Qcm9wc10uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgICByZXN0UHJvcHNbZXZlbnROYW1lXS5hcHBseShyZXN0UHJvcHMsIGFyZ3MpO1xuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gQ2hpbGQgTm9kZVxuICAgIHZhciB0cmlnZ2VyTm9kZSA9IC8qI19fUFVSRV9fKi9SZWFjdC5jbG9uZUVsZW1lbnQoY2hpbGQsIF9vYmplY3RTcHJlYWQoX29iamVjdFNwcmVhZCh7fSwgbWVyZ2VkQ2hpbGRyZW5Qcm9wcyksIHBhc3NlZFByb3BzKSk7XG4gICAgdmFyIGFycm93UG9zID0ge1xuICAgICAgeDogYXJyb3dYLFxuICAgICAgeTogYXJyb3dZXG4gICAgfTtcbiAgICB2YXIgaW5uZXJBcnJvdyA9IGFycm93ID8gX29iamVjdFNwcmVhZCh7fSwgYXJyb3cgIT09IHRydWUgPyBhcnJvdyA6IHt9KSA6IG51bGw7XG5cbiAgICAvLyBSZW5kZXJcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3QuRnJhZ21lbnQsIG51bGwsIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFJlc2l6ZU9ic2VydmVyLCB7XG4gICAgICBkaXNhYmxlZDogIW1lcmdlZE9wZW4sXG4gICAgICByZWY6IHNldFRhcmdldFJlZixcbiAgICAgIG9uUmVzaXplOiBvblRhcmdldFJlc2l6ZVxuICAgIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFRyaWdnZXJXcmFwcGVyLCB7XG4gICAgICBnZXRUcmlnZ2VyRE9NTm9kZTogZ2V0VHJpZ2dlckRPTU5vZGVcbiAgICB9LCB0cmlnZ2VyTm9kZSkpLCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChUcmlnZ2VyQ29udGV4dC5Qcm92aWRlciwge1xuICAgICAgdmFsdWU6IGNvbnRleHRcbiAgICB9LCAvKiNfX1BVUkVfXyovUmVhY3QuY3JlYXRlRWxlbWVudChQb3B1cCwge1xuICAgICAgcG9ydGFsOiBQb3J0YWxDb21wb25lbnQsXG4gICAgICByZWY6IHNldFBvcHVwUmVmLFxuICAgICAgcHJlZml4Q2xzOiBwcmVmaXhDbHMsXG4gICAgICBwb3B1cDogcG9wdXAsXG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMocG9wdXBDbGFzc05hbWUsIGFsaWduZWRDbGFzc05hbWUpLFxuICAgICAgc3R5bGU6IHBvcHVwU3R5bGUsXG4gICAgICB0YXJnZXQ6IHRhcmdldEVsZSxcbiAgICAgIG9uTW91c2VFbnRlcjogb25Qb3B1cE1vdXNlRW50ZXIsXG4gICAgICBvbk1vdXNlTGVhdmU6IG9uUG9wdXBNb3VzZUxlYXZlLFxuICAgICAgekluZGV4OiB6SW5kZXhcbiAgICAgIC8vIE9wZW5cbiAgICAgICxcbiAgICAgIG9wZW46IG1lcmdlZE9wZW4sXG4gICAgICBrZWVwRG9tOiBpbk1vdGlvblxuICAgICAgLy8gQ2xpY2tcbiAgICAgICxcbiAgICAgIG9uQ2xpY2s6IG9uUG9wdXBDbGlja1xuICAgICAgLy8gTWFza1xuICAgICAgLFxuICAgICAgbWFzazogbWFza1xuICAgICAgLy8gTW90aW9uXG4gICAgICAsXG4gICAgICBtb3Rpb246IG1lcmdlUG9wdXBNb3Rpb24sXG4gICAgICBtYXNrTW90aW9uOiBtZXJnZU1hc2tNb3Rpb24sXG4gICAgICBvblZpc2libGVDaGFuZ2VkOiBvblZpc2libGVDaGFuZ2VkLFxuICAgICAgb25QcmVwYXJlOiBvblByZXBhcmVcbiAgICAgIC8vIFBvcnRhbFxuICAgICAgLFxuICAgICAgZm9yY2VSZW5kZXI6IGZvcmNlUmVuZGVyLFxuICAgICAgYXV0b0Rlc3Ryb3k6IG1lcmdlZEF1dG9EZXN0cm95LFxuICAgICAgZ2V0UG9wdXBDb250YWluZXI6IGdldFBvcHVwQ29udGFpbmVyXG4gICAgICAvLyBBcnJvd1xuICAgICAgLFxuICAgICAgYWxpZ246IGFsaWduSW5mbyxcbiAgICAgIGFycm93OiBpbm5lckFycm93LFxuICAgICAgYXJyb3dQb3M6IGFycm93UG9zXG4gICAgICAvLyBBbGlnblxuICAgICAgLFxuICAgICAgcmVhZHk6IHJlYWR5LFxuICAgICAgb2Zmc2V0WDogb2Zmc2V0WCxcbiAgICAgIG9mZnNldFk6IG9mZnNldFksXG4gICAgICBvbkFsaWduOiB0cmlnZ2VyQWxpZ25cbiAgICAgIC8vIFN0cmV0Y2hcbiAgICAgICxcbiAgICAgIHN0cmV0Y2g6IHN0cmV0Y2gsXG4gICAgICB0YXJnZXRXaWR0aDogdGFyZ2V0V2lkdGggLyBzY2FsZVgsXG4gICAgICB0YXJnZXRIZWlnaHQ6IHRhcmdldEhlaWdodCAvIHNjYWxlWVxuICAgIH0pKSk7XG4gIH0pO1xuICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJykge1xuICAgIFRyaWdnZXIuZGlzcGxheU5hbWUgPSAnVHJpZ2dlcic7XG4gIH1cbiAgcmV0dXJuIFRyaWdnZXI7XG59XG5leHBvcnQgZGVmYXVsdCBnZW5lcmF0ZVRyaWdnZXIoUG9ydGFsKTsiLCJ2YXIgYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tID0ge1xuICBzaGlmdFg6IDY0LFxuICBhZGp1c3RZOiAxXG59O1xudmFyIGF1dG9BZGp1c3RPdmVyZmxvd0xlZnRSaWdodCA9IHtcbiAgYWRqdXN0WDogMSxcbiAgc2hpZnRZOiB0cnVlXG59O1xudmFyIHRhcmdldE9mZnNldCA9IFswLCAwXTtcbmV4cG9ydCB2YXIgcGxhY2VtZW50cyA9IHtcbiAgbGVmdDoge1xuICAgIHBvaW50czogWydjcicsICdjbCddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbLTQsIDBdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH0sXG4gIHJpZ2h0OiB7XG4gICAgcG9pbnRzOiBbJ2NsJywgJ2NyJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd0xlZnRSaWdodCxcbiAgICBvZmZzZXQ6IFs0LCAwXSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICB0b3A6IHtcbiAgICBwb2ludHM6IFsnYmMnLCAndGMnXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tLFxuICAgIG9mZnNldDogWzAsIC00XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICBib3R0b206IHtcbiAgICBwb2ludHM6IFsndGMnLCAnYmMnXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tLFxuICAgIG9mZnNldDogWzAsIDRdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH0sXG4gIHRvcExlZnQ6IHtcbiAgICBwb2ludHM6IFsnYmwnLCAndGwnXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tLFxuICAgIG9mZnNldDogWzAsIC00XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICBsZWZ0VG9wOiB7XG4gICAgcG9pbnRzOiBbJ3RyJywgJ3RsJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd0xlZnRSaWdodCxcbiAgICBvZmZzZXQ6IFstNCwgMF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgdG9wUmlnaHQ6IHtcbiAgICBwb2ludHM6IFsnYnInLCAndHInXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tLFxuICAgIG9mZnNldDogWzAsIC00XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICByaWdodFRvcDoge1xuICAgIHBvaW50czogWyd0bCcsICd0ciddLFxuICAgIG92ZXJmbG93OiBhdXRvQWRqdXN0T3ZlcmZsb3dMZWZ0UmlnaHQsXG4gICAgb2Zmc2V0OiBbNCwgMF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfSxcbiAgYm90dG9tUmlnaHQ6IHtcbiAgICBwb2ludHM6IFsndHInLCAnYnInXSxcbiAgICBvdmVyZmxvdzogYXV0b0FkanVzdE92ZXJmbG93VG9wQm90dG9tLFxuICAgIG9mZnNldDogWzAsIDRdLFxuICAgIHRhcmdldE9mZnNldDogdGFyZ2V0T2Zmc2V0XG4gIH0sXG4gIHJpZ2h0Qm90dG9tOiB7XG4gICAgcG9pbnRzOiBbJ2JsJywgJ2JyJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd0xlZnRSaWdodCxcbiAgICBvZmZzZXQ6IFs0LCAwXSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICBib3R0b21MZWZ0OiB7XG4gICAgcG9pbnRzOiBbJ3RsJywgJ2JsJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd1RvcEJvdHRvbSxcbiAgICBvZmZzZXQ6IFswLCA0XSxcbiAgICB0YXJnZXRPZmZzZXQ6IHRhcmdldE9mZnNldFxuICB9LFxuICBsZWZ0Qm90dG9tOiB7XG4gICAgcG9pbnRzOiBbJ2JyJywgJ2JsJ10sXG4gICAgb3ZlcmZsb3c6IGF1dG9BZGp1c3RPdmVyZmxvd0xlZnRSaWdodCxcbiAgICBvZmZzZXQ6IFstNCwgMF0sXG4gICAgdGFyZ2V0T2Zmc2V0OiB0YXJnZXRPZmZzZXRcbiAgfVxufTtcbmV4cG9ydCBkZWZhdWx0IHBsYWNlbWVudHM7IiwiaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQb3B1cChwcm9wcykge1xuICB2YXIgY2hpbGRyZW4gPSBwcm9wcy5jaGlsZHJlbixcbiAgICBwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgaWQgPSBwcm9wcy5pZCxcbiAgICBvdmVybGF5SW5uZXJTdHlsZSA9IHByb3BzLm92ZXJsYXlJbm5lclN0eWxlLFxuICAgIGNsYXNzTmFtZSA9IHByb3BzLmNsYXNzTmFtZSxcbiAgICBzdHlsZSA9IHByb3BzLnN0eWxlO1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge1xuICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lcyhcIlwiLmNvbmNhdChwcmVmaXhDbHMsIFwiLWNvbnRlbnRcIiksIGNsYXNzTmFtZSksXG4gICAgc3R5bGU6IHN0eWxlXG4gIH0sIC8qI19fUFVSRV9fKi9SZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtcbiAgICBjbGFzc05hbWU6IFwiXCIuY29uY2F0KHByZWZpeENscywgXCItaW5uZXJcIiksXG4gICAgaWQ6IGlkLFxuICAgIHJvbGU6IFwidG9vbHRpcFwiLFxuICAgIHN0eWxlOiBvdmVybGF5SW5uZXJTdHlsZVxuICB9LCB0eXBlb2YgY2hpbGRyZW4gPT09ICdmdW5jdGlvbicgPyBjaGlsZHJlbigpIDogY2hpbGRyZW4pKTtcbn0iLCJpbXBvcnQgX2V4dGVuZHMgZnJvbSBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZXNtL2V4dGVuZHNcIjtcbmltcG9ydCBfb2JqZWN0U3ByZWFkIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RTcHJlYWQyXCI7XG5pbXBvcnQgX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzIGZyb20gXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2VzbS9vYmplY3RXaXRob3V0UHJvcGVydGllc1wiO1xudmFyIF9leGNsdWRlZCA9IFtcIm92ZXJsYXlDbGFzc05hbWVcIiwgXCJ0cmlnZ2VyXCIsIFwibW91c2VFbnRlckRlbGF5XCIsIFwibW91c2VMZWF2ZURlbGF5XCIsIFwib3ZlcmxheVN0eWxlXCIsIFwicHJlZml4Q2xzXCIsIFwiY2hpbGRyZW5cIiwgXCJvblZpc2libGVDaGFuZ2VcIiwgXCJhZnRlclZpc2libGVDaGFuZ2VcIiwgXCJ0cmFuc2l0aW9uTmFtZVwiLCBcImFuaW1hdGlvblwiLCBcIm1vdGlvblwiLCBcInBsYWNlbWVudFwiLCBcImFsaWduXCIsIFwiZGVzdHJveVRvb2x0aXBPbkhpZGVcIiwgXCJkZWZhdWx0VmlzaWJsZVwiLCBcImdldFRvb2x0aXBDb250YWluZXJcIiwgXCJvdmVybGF5SW5uZXJTdHlsZVwiLCBcImFycm93Q29udGVudFwiLCBcIm92ZXJsYXlcIiwgXCJpZFwiLCBcInNob3dBcnJvd1wiXTtcbmltcG9ydCBUcmlnZ2VyIGZyb20gJ0ByYy1jb21wb25lbnQvdHJpZ2dlcic7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBmb3J3YXJkUmVmLCB1c2VJbXBlcmF0aXZlSGFuZGxlLCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBwbGFjZW1lbnRzIH0gZnJvbSBcIi4vcGxhY2VtZW50c1wiO1xuaW1wb3J0IFBvcHVwIGZyb20gXCIuL1BvcHVwXCI7XG52YXIgVG9vbHRpcCA9IGZ1bmN0aW9uIFRvb2x0aXAocHJvcHMsIHJlZikge1xuICB2YXIgb3ZlcmxheUNsYXNzTmFtZSA9IHByb3BzLm92ZXJsYXlDbGFzc05hbWUsXG4gICAgX3Byb3BzJHRyaWdnZXIgPSBwcm9wcy50cmlnZ2VyLFxuICAgIHRyaWdnZXIgPSBfcHJvcHMkdHJpZ2dlciA9PT0gdm9pZCAwID8gWydob3ZlciddIDogX3Byb3BzJHRyaWdnZXIsXG4gICAgX3Byb3BzJG1vdXNlRW50ZXJEZWxhID0gcHJvcHMubW91c2VFbnRlckRlbGF5LFxuICAgIG1vdXNlRW50ZXJEZWxheSA9IF9wcm9wcyRtb3VzZUVudGVyRGVsYSA9PT0gdm9pZCAwID8gMCA6IF9wcm9wcyRtb3VzZUVudGVyRGVsYSxcbiAgICBfcHJvcHMkbW91c2VMZWF2ZURlbGEgPSBwcm9wcy5tb3VzZUxlYXZlRGVsYXksXG4gICAgbW91c2VMZWF2ZURlbGF5ID0gX3Byb3BzJG1vdXNlTGVhdmVEZWxhID09PSB2b2lkIDAgPyAwLjEgOiBfcHJvcHMkbW91c2VMZWF2ZURlbGEsXG4gICAgb3ZlcmxheVN0eWxlID0gcHJvcHMub3ZlcmxheVN0eWxlLFxuICAgIF9wcm9wcyRwcmVmaXhDbHMgPSBwcm9wcy5wcmVmaXhDbHMsXG4gICAgcHJlZml4Q2xzID0gX3Byb3BzJHByZWZpeENscyA9PT0gdm9pZCAwID8gJ3JjLXRvb2x0aXAnIDogX3Byb3BzJHByZWZpeENscyxcbiAgICBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLFxuICAgIG9uVmlzaWJsZUNoYW5nZSA9IHByb3BzLm9uVmlzaWJsZUNoYW5nZSxcbiAgICBhZnRlclZpc2libGVDaGFuZ2UgPSBwcm9wcy5hZnRlclZpc2libGVDaGFuZ2UsXG4gICAgdHJhbnNpdGlvbk5hbWUgPSBwcm9wcy50cmFuc2l0aW9uTmFtZSxcbiAgICBhbmltYXRpb24gPSBwcm9wcy5hbmltYXRpb24sXG4gICAgbW90aW9uID0gcHJvcHMubW90aW9uLFxuICAgIF9wcm9wcyRwbGFjZW1lbnQgPSBwcm9wcy5wbGFjZW1lbnQsXG4gICAgcGxhY2VtZW50ID0gX3Byb3BzJHBsYWNlbWVudCA9PT0gdm9pZCAwID8gJ3JpZ2h0JyA6IF9wcm9wcyRwbGFjZW1lbnQsXG4gICAgX3Byb3BzJGFsaWduID0gcHJvcHMuYWxpZ24sXG4gICAgYWxpZ24gPSBfcHJvcHMkYWxpZ24gPT09IHZvaWQgMCA/IHt9IDogX3Byb3BzJGFsaWduLFxuICAgIF9wcm9wcyRkZXN0cm95VG9vbHRpcCA9IHByb3BzLmRlc3Ryb3lUb29sdGlwT25IaWRlLFxuICAgIGRlc3Ryb3lUb29sdGlwT25IaWRlID0gX3Byb3BzJGRlc3Ryb3lUb29sdGlwID09PSB2b2lkIDAgPyBmYWxzZSA6IF9wcm9wcyRkZXN0cm95VG9vbHRpcCxcbiAgICBkZWZhdWx0VmlzaWJsZSA9IHByb3BzLmRlZmF1bHRWaXNpYmxlLFxuICAgIGdldFRvb2x0aXBDb250YWluZXIgPSBwcm9wcy5nZXRUb29sdGlwQ29udGFpbmVyLFxuICAgIG92ZXJsYXlJbm5lclN0eWxlID0gcHJvcHMub3ZlcmxheUlubmVyU3R5bGUsXG4gICAgYXJyb3dDb250ZW50ID0gcHJvcHMuYXJyb3dDb250ZW50LFxuICAgIG92ZXJsYXkgPSBwcm9wcy5vdmVybGF5LFxuICAgIGlkID0gcHJvcHMuaWQsXG4gICAgX3Byb3BzJHNob3dBcnJvdyA9IHByb3BzLnNob3dBcnJvdyxcbiAgICBzaG93QXJyb3cgPSBfcHJvcHMkc2hvd0Fycm93ID09PSB2b2lkIDAgPyB0cnVlIDogX3Byb3BzJHNob3dBcnJvdyxcbiAgICByZXN0UHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIF9leGNsdWRlZCk7XG4gIHZhciB0cmlnZ2VyUmVmID0gdXNlUmVmKG51bGwpO1xuICB1c2VJbXBlcmF0aXZlSGFuZGxlKHJlZiwgZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0cmlnZ2VyUmVmLmN1cnJlbnQ7XG4gIH0pO1xuICB2YXIgZXh0cmFQcm9wcyA9IF9vYmplY3RTcHJlYWQoe30sIHJlc3RQcm9wcyk7XG4gIGlmICgndmlzaWJsZScgaW4gcHJvcHMpIHtcbiAgICBleHRyYVByb3BzLnBvcHVwVmlzaWJsZSA9IHByb3BzLnZpc2libGU7XG4gIH1cbiAgdmFyIGdldFBvcHVwRWxlbWVudCA9IGZ1bmN0aW9uIGdldFBvcHVwRWxlbWVudCgpIHtcbiAgICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoUG9wdXAsIHtcbiAgICAgIGtleTogXCJjb250ZW50XCIsXG4gICAgICBwcmVmaXhDbHM6IHByZWZpeENscyxcbiAgICAgIGlkOiBpZCxcbiAgICAgIG92ZXJsYXlJbm5lclN0eWxlOiBvdmVybGF5SW5uZXJTdHlsZVxuICAgIH0sIG92ZXJsYXkpO1xuICB9O1xuICByZXR1cm4gLyojX19QVVJFX18qL1JlYWN0LmNyZWF0ZUVsZW1lbnQoVHJpZ2dlciwgX2V4dGVuZHMoe1xuICAgIHBvcHVwQ2xhc3NOYW1lOiBvdmVybGF5Q2xhc3NOYW1lLFxuICAgIHByZWZpeENsczogcHJlZml4Q2xzLFxuICAgIHBvcHVwOiBnZXRQb3B1cEVsZW1lbnQsXG4gICAgYWN0aW9uOiB0cmlnZ2VyLFxuICAgIGJ1aWx0aW5QbGFjZW1lbnRzOiBwbGFjZW1lbnRzLFxuICAgIHBvcHVwUGxhY2VtZW50OiBwbGFjZW1lbnQsXG4gICAgcmVmOiB0cmlnZ2VyUmVmLFxuICAgIHBvcHVwQWxpZ246IGFsaWduLFxuICAgIGdldFBvcHVwQ29udGFpbmVyOiBnZXRUb29sdGlwQ29udGFpbmVyLFxuICAgIG9uUG9wdXBWaXNpYmxlQ2hhbmdlOiBvblZpc2libGVDaGFuZ2UsXG4gICAgYWZ0ZXJQb3B1cFZpc2libGVDaGFuZ2U6IGFmdGVyVmlzaWJsZUNoYW5nZSxcbiAgICBwb3B1cFRyYW5zaXRpb25OYW1lOiB0cmFuc2l0aW9uTmFtZSxcbiAgICBwb3B1cEFuaW1hdGlvbjogYW5pbWF0aW9uLFxuICAgIHBvcHVwTW90aW9uOiBtb3Rpb24sXG4gICAgZGVmYXVsdFBvcHVwVmlzaWJsZTogZGVmYXVsdFZpc2libGUsXG4gICAgYXV0b0Rlc3Ryb3k6IGRlc3Ryb3lUb29sdGlwT25IaWRlLFxuICAgIG1vdXNlTGVhdmVEZWxheTogbW91c2VMZWF2ZURlbGF5LFxuICAgIHBvcHVwU3R5bGU6IG92ZXJsYXlTdHlsZSxcbiAgICBtb3VzZUVudGVyRGVsYXk6IG1vdXNlRW50ZXJEZWxheSxcbiAgICBhcnJvdzogc2hvd0Fycm93XG4gIH0sIGV4dHJhUHJvcHMpLCBjaGlsZHJlbik7XG59O1xuZXhwb3J0IGRlZmF1bHQgLyojX19QVVJFX18qL2ZvcndhcmRSZWYoVG9vbHRpcCk7IiwiaW1wb3J0IFRvb2x0aXAgZnJvbSBcIi4vVG9vbHRpcFwiO1xuaW1wb3J0IFBvcHVwIGZyb20gXCIuL1BvcHVwXCI7XG5leHBvcnQgeyBQb3B1cCB9O1xuZXhwb3J0IGRlZmF1bHQgVG9vbHRpcDsiLCIvKipcbiAqIHJjLXRvb2x0aXAgdG9vbHRpcCBzbGlkZXJcbiAqL1xudmFyIF9fYXNzaWduID0gKHRoaXMgJiYgdGhpcy5fX2Fzc2lnbikgfHwgZnVuY3Rpb24gKCkge1xuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbih0KSB7XG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSlcbiAgICAgICAgICAgICAgICB0W3BdID0gc1twXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdDtcbiAgICB9O1xuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcbnZhciBfX3Jlc3QgPSAodGhpcyAmJiB0aGlzLl9fcmVzdCkgfHwgZnVuY3Rpb24gKHMsIGUpIHtcbiAgICB2YXIgdCA9IHt9O1xuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxuICAgICAgICB0W3BdID0gc1twXTtcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcbiAgICAgICAgfVxuICAgIHJldHVybiB0O1xufTtcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IFwicmMtdG9vbHRpcC9hc3NldHMvYm9vdHN0cmFwLmNzc1wiO1xuaW1wb3J0IFNsaWRlciBmcm9tIFwicmMtc2xpZGVyXCI7XG5pbXBvcnQgcmFmIGZyb20gXCJyYy11dGlsL2xpYi9yYWZcIjtcbmltcG9ydCBUb29sdGlwIGZyb20gXCJyYy10b29sdGlwXCI7XG52YXIgSGFuZGxlVG9vbHRpcCA9IGZ1bmN0aW9uIChwcm9wcykge1xuICAgIHZhciB2YWx1ZSA9IHByb3BzLnZhbHVlLCBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuLCB2aXNpYmxlID0gcHJvcHMudmlzaWJsZSwgX2EgPSBwcm9wcy50aXBGb3JtYXR0ZXIsIHRpcEZvcm1hdHRlciA9IF9hID09PSB2b2lkIDAgPyBmdW5jdGlvbiAodmFsKSB7IHJldHVybiBcIlwiLmNvbmNhdCh2YWwsIFwiICVcIik7IH0gOiBfYSwgcmVzdFByb3BzID0gX19yZXN0KHByb3BzLCBbXCJ2YWx1ZVwiLCBcImNoaWxkcmVuXCIsIFwidmlzaWJsZVwiLCBcInRpcEZvcm1hdHRlclwiXSk7XG4gICAgdmFyIHRvb2x0aXBSZWYgPSBSZWFjdC51c2VSZWYoKTtcbiAgICB2YXIgcmFmUmVmID0gUmVhY3QudXNlUmVmKG51bGwpO1xuICAgIGZ1bmN0aW9uIGNhbmNlbEtlZXBBbGlnbigpIHtcbiAgICAgICAgcmFmLmNhbmNlbChyYWZSZWYuY3VycmVudCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGtlZXBBbGlnbigpIHtcbiAgICAgICAgcmFmUmVmLmN1cnJlbnQgPSByYWYoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gdG9vbHRpcFJlZi5jdXJyZW50Py5mb3JjZVBvcHVwQWxpZ24oKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIFJlYWN0LnVzZUVmZmVjdChmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh2aXNpYmxlKSB7XG4gICAgICAgICAgICBrZWVwQWxpZ24oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNhbmNlbEtlZXBBbGlnbigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYW5jZWxLZWVwQWxpZ247XG4gICAgfSwgW3ZhbHVlLCB2aXNpYmxlXSk7XG4gICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KFRvb2x0aXAsIF9fYXNzaWduKHsgcGxhY2VtZW50OiBcInRvcFwiLCBvdmVybGF5OiB0aXBGb3JtYXR0ZXIodmFsdWUpLCBvdmVybGF5SW5uZXJTdHlsZTogeyBtaW5IZWlnaHQ6IFwiYXV0b1wiIH0sIHJlZjogdG9vbHRpcFJlZiwgdmlzaWJsZTogdmlzaWJsZSB9LCByZXN0UHJvcHMpLCBjaGlsZHJlbikpO1xufTtcbmV4cG9ydCB2YXIgaGFuZGxlUmVuZGVyID0gZnVuY3Rpb24gKG5vZGUsIHByb3BzKSB7XG4gICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KEhhbmRsZVRvb2x0aXAsIHsgdmFsdWU6IHByb3BzLnZhbHVlLCB2aXNpYmxlOiBwcm9wcy5kcmFnZ2luZyB9LCBub2RlKSk7XG59O1xudmFyIFRvb2x0aXBTbGlkZXIgPSBmdW5jdGlvbiAoX2EpIHtcbiAgICB2YXIgdGlwRm9ybWF0dGVyID0gX2EudGlwRm9ybWF0dGVyLCB0aXBQcm9wcyA9IF9hLnRpcFByb3BzLCBwcm9wcyA9IF9fcmVzdChfYSwgW1widGlwRm9ybWF0dGVyXCIsIFwidGlwUHJvcHNcIl0pO1xuICAgIHZhciB0aXBIYW5kbGVSZW5kZXIgPSBmdW5jdGlvbiAobm9kZSwgaGFuZGxlUHJvcHMpIHtcbiAgICAgICAgcmV0dXJuIChSZWFjdC5jcmVhdGVFbGVtZW50KEhhbmRsZVRvb2x0aXAsIF9fYXNzaWduKHsgdmFsdWU6IGhhbmRsZVByb3BzLnZhbHVlLCB2aXNpYmxlOiBoYW5kbGVQcm9wcy5kcmFnZ2luZywgdGlwRm9ybWF0dGVyOiB0aXBGb3JtYXR0ZXIgfSwgdGlwUHJvcHMpLCBub2RlKSk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChTbGlkZXIsIF9fYXNzaWduKHt9LCBwcm9wcywgeyBoYW5kbGVSZW5kZXI6IHRpcEhhbmRsZVJlbmRlciB9KSk7XG59O1xuZXhwb3J0IGRlZmF1bHQgVG9vbHRpcFNsaWRlcjtcbiIsIlxuICAgICAgaW1wb3J0IEFQSSBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qc1wiO1xuICAgICAgaW1wb3J0IGluc2VydEZuIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRCeVNlbGVjdG9yLmpzXCI7XG4gICAgICBpbXBvcnQgc2V0QXR0cmlidXRlcyBmcm9tIFwiIS4uLy4uL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanNcIjtcbiAgICAgIGltcG9ydCBzdHlsZVRhZ1RyYW5zZm9ybUZuIGZyb20gXCIhLi4vLi4vc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qc1wiO1xuICAgICAgaW1wb3J0IGNvbnRlbnQsICogYXMgbmFtZWRFeHBvcnQgZnJvbSBcIiEhLi4vLi4vY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL2luZGV4LmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xuXG4gICAgICBvcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xuICAgIFxub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uLy4uL2Nzcy1sb2FkZXIvZGlzdC9janMuanMhLi9pbmRleC5jc3NcIjtcbiAgICAgICBleHBvcnQgZGVmYXVsdCBjb250ZW50ICYmIGNvbnRlbnQubG9jYWxzID8gY29udGVudC5sb2NhbHMgOiB1bmRlZmluZWQ7XG4iLCIvKipcbiAqIFJlbGFiaSBjb250cm9sc1xuICogQG1vZHVsZSBzcmMvdWkvQ29udHJvbHMuanN4O1xuICovXG5cbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZVJlZiB9IGZyb20gXCJyZWFjdFwiO1xuXG5pbXBvcnQgU2xpZGVyIGZyb20gXCJyYy1zbGlkZXJcIjtcbmltcG9ydCBUb29sdGlwU2xpZGVyLCB7IGhhbmRsZVJlbmRlciB9IGZyb20gXCIuL1Rvb2x0aXBTbGlkZXIudHN4XCI7XG5pbXBvcnQgXCJyYy1zbGlkZXIvYXNzZXRzL2luZGV4LmNzc1wiO1xuXG5jb25zdCBXQVZFX1NIQVBFX05BTUVTID0gW1wic2luZVwiLCBcInRyaWFuZ2xlXCIsIFwic2F3XCIsIFwicmV2ZXJzZV9zYXdcIiwgXCJzcXVhcmVcIl07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbnRyb2xzKHsgcmVsYWJpIH0pIHtcbiAgLyoqXG4gICAqIEhhbmRsZSB1cGRhdGluZyBhIHNsaWRlclxuICAgKi9cbiAgY29uc3Qgb25DaGFuZ2UgPSB1c2VDYWxsYmFjayhcbiAgICAodHlwZSwgaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgaWYgKHR5cGUgPT09IFwiYm91bmRcIikge1xuICAgICAgICByZWxhYmkuYm91bmRzW2luZGV4XS5sZXZlbCA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGUgPT09IFwic2hhcGVcIikge1xuICAgICAgICByZWxhYmkud2F2ZXNbaW5kZXhdLnNoYXBlID0gV0FWRV9TSEFQRV9OQU1FU1t2YWx1ZV07XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gXCJmcmVxdWVuY3lcIikge1xuICAgICAgICByZWxhYmkud2F2ZXNbaW5kZXhdLmZyZXF1ZW5jeSA9IE1hdGguZXhwKHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlID09PSBcIndlaWdodFwiKSB7XG4gICAgICAgIHJlbGFiaS53YXZlc1tpbmRleF0ud2VpZ2h0ID0gdmFsdWU7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSA9PT0gXCJzZXR0aW5nc1wiKSB7XG4gICAgICAgIHJlbGFiaS5zZXR0aW5nc1tpbmRleF0gPSBpbmRleCA9PT0gXCJzcGVlZFwiID8gTWF0aC5leHAodmFsdWUpIDogdmFsdWU7XG4gICAgICB9XG4gICAgfSxcbiAgICBbcmVsYWJpXVxuICApO1xuXG4gIGlmICghcmVsYWJpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxDb250cm9sUm93PlxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5Cb3VuZHM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LmJvdW5kcy5tYXAoKGJvdW5kLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgYm91bmRfJHtpbmRleH1gfVxuICAgICAgICAgICAgICB0eXBlPVwiYm91bmRcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXstMX1cbiAgICAgICAgICAgICAgbWF4PXsxfVxuICAgICAgICAgICAgICBzdGVwPXswLjAxfVxuICAgICAgICAgICAgICB0aXBGb3JtYXR0ZXI9eyh2YWx1ZSkgPT4gLXZhbHVlfVxuICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU9e2JvdW5kLmxldmVsfVxuICAgICAgICAgICAgICBjb2xvcj17Ym91bmQuY29sb3J9XG4gICAgICAgICAgICAgIHJldmVyc2VcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuXG4gICAgICA8Q29udHJvbEJveD5cbiAgICAgICAgPExhYmVsPldhdmUgZnJlcXVlbmNpZXM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LndhdmVzLm1hcCgod2F2ZSwgaW5kZXgpID0+IChcbiAgICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICAgIHJlbD17YGZyZXF1ZW5jeV8ke2luZGV4fWB9XG4gICAgICAgICAgICAgIHR5cGU9XCJmcmVxdWVuY3lcIlxuICAgICAgICAgICAgICBpbmRleD17aW5kZXh9XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgICAgbWluPXstMn1cbiAgICAgICAgICAgICAgbWF4PXszfVxuICAgICAgICAgICAgICBzdGVwPXswLjAwMX1cbiAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlPXtNYXRoLmxvZyh3YXZlLmZyZXF1ZW5jeSl9XG4gICAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBNYXRoLmV4cCh2YWx1ZSkudG9GaXhlZCgxKX1cbiAgICAgICAgICAgICAgY29sb3I9e1wiIzhhOFwifVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9TbGlkZXJSb3c+XG4gICAgICA8L0NvbnRyb2xCb3g+XG5cbiAgICAgIDxDb250cm9sQm94PlxuICAgICAgICA8TGFiZWw+V2F2ZSBzaGFwZXM8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIHtyZWxhYmk/LndhdmVzLm1hcCgod2F2ZSwgaW5kZXgpID0+IChcbiAgICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICAgIHJlbD17YHNoYXBlXyR7aW5kZXh9YH1cbiAgICAgICAgICAgICAgdHlwZT1cInNoYXBlXCJcbiAgICAgICAgICAgICAgaW5kZXg9e2luZGV4fVxuICAgICAgICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAgICAgICAgIG1pbj17MH1cbiAgICAgICAgICAgICAgbWF4PXtXQVZFX1NIQVBFX05BTUVTLmxlbmd0aCAtIDF9XG4gICAgICAgICAgICAgIHN0ZXA9ezF9XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17V0FWRV9TSEFQRV9OQU1FUy5pbmRleE9mKHdhdmUuc2hhcGUpfVxuICAgICAgICAgICAgICBjb2xvcj17XCIjYWE4XCJ9XG4gICAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBXQVZFX1NIQVBFX05BTUVTW3ZhbHVlXX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSl9XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuXG4gICAgICA8Q29udHJvbEJveD5cbiAgICAgICAgPExhYmVsPldhdmUgd2VpZ2h0czwvTGFiZWw+XG4gICAgICAgIDxTbGlkZXJSb3c+XG4gICAgICAgICAge3JlbGFiaT8ud2F2ZXMubWFwKCh3YXZlLCBpbmRleCkgPT4gKFxuICAgICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgICAgcmVsPXtgd2VpZ2h0XyR7aW5kZXh9YH1cbiAgICAgICAgICAgICAgdHlwZT1cIndlaWdodFwiXG4gICAgICAgICAgICAgIGluZGV4PXtpbmRleH1cbiAgICAgICAgICAgICAgb25DaGFuZ2U9e29uQ2hhbmdlfVxuICAgICAgICAgICAgICBtaW49ezB9XG4gICAgICAgICAgICAgIG1heD17Mn1cbiAgICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlPXt3YXZlLndlaWdodH1cbiAgICAgICAgICAgICAgY29sb3I9e1wiIzk5YlwifVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9TbGlkZXJSb3c+XG4gICAgICA8L0NvbnRyb2xCb3g+XG5cbiAgICAgIDxDb250cm9sQm94PlxuICAgICAgICA8TGFiZWw+U3BlZWQ8L0xhYmVsPlxuICAgICAgICA8U2xpZGVyUm93PlxuICAgICAgICAgIDxDb250cm9sU2xpZGVyXG4gICAgICAgICAgICB0eXBlPVwic2V0dGluZ3NcIlxuICAgICAgICAgICAgaW5kZXg9XCJzcGVlZFwiXG4gICAgICAgICAgICBvbkNoYW5nZT17b25DaGFuZ2V9XG4gICAgICAgICAgICBtaW49ey0yfVxuICAgICAgICAgICAgbWF4PXszfVxuICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17TWF0aC5sb2cocmVsYWJpLnNldHRpbmdzLnNwZWVkKX1cbiAgICAgICAgICAgIHRpcEZvcm1hdHRlcj17KHZhbHVlKSA9PiBNYXRoLmV4cCh2YWx1ZSkudG9GaXhlZCgxKX1cbiAgICAgICAgICAgIGNvbG9yPXtcIiNhODhcIn1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1NsaWRlclJvdz5cbiAgICAgIDwvQ29udHJvbEJveD5cblxuICAgICAgPENvbnRyb2xCb3g+XG4gICAgICAgIDxMYWJlbD5DaGFvczwvTGFiZWw+XG4gICAgICAgIDxTbGlkZXJSb3c+XG4gICAgICAgICAgPENvbnRyb2xTbGlkZXJcbiAgICAgICAgICAgIHR5cGU9XCJzZXR0aW5nc1wiXG4gICAgICAgICAgICBpbmRleD1cImZlZWRiYWNrXCJcbiAgICAgICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgICAgIG1pbj17MH1cbiAgICAgICAgICAgIG1heD17MC41fVxuICAgICAgICAgICAgc3RlcD17MC4wMX1cbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZT17cmVsYWJpLnNldHRpbmdzLmZlZWRiYWNrfVxuICAgICAgICAgICAgY29sb3I9e1wiI2E4OFwifVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvU2xpZGVyUm93PlxuICAgICAgPC9Db250cm9sQm94PlxuICAgIDwvQ29udHJvbFJvdz5cbiAgKTtcbn1cblxuLyoqXG4gKiBVSSBFbGVtZW50c1xuICovXG5jb25zdCBDb250cm9sUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjdGlvbjogXCJyb3dcIixcbiAgICAgIG1hcmdpblRvcDogXCIxcmVtXCIsXG4gICAgfX1cbiAgPlxuICAgIHtjaGlsZHJlbn1cbiAgPC9kaXY+XG4pO1xuXG5jb25zdCBDb250cm9sQm94ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIG1hcmdpbkxlZnQ6IFwiMXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgU2xpZGVyUm93ID0gKHsgY2hpbGRyZW4gfSkgPT4gKFxuICA8ZGl2XG4gICAgc3R5bGU9e3tcbiAgICAgIGRpc3BsYXk6IFwiZmxleFwiLFxuICAgICAgZmxleERpcmVjaXRvbjogXCJyb3dcIixcbiAgICAgIGhlaWdodDogXCIxMHJlbVwiLFxuICAgICAgbWFyZ2luVG9wOiBcIjAuNXJlbVwiLFxuICAgIH19XG4gID5cbiAgICB7Y2hpbGRyZW59XG4gIDwvZGl2PlxuKTtcblxuY29uc3QgTGFiZWwgPSAoeyBjaGlsZHJlbiB9KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgZm9udFNpemU6IFwiMC43NXJlbVwiIH19PntjaGlsZHJlbn08L2Rpdj5cbik7XG5cbmNvbnN0IENvbnRyb2xTbGlkZXIgPSAoe1xuICB0eXBlLFxuICBpbmRleCxcbiAgbWluLFxuICBtYXgsXG4gIHN0ZXAsXG4gIHJldmVyc2UsXG4gIGRlZmF1bHRWYWx1ZSxcbiAgY29sb3IsXG4gIG9uQ2hhbmdlLFxuICB0aXBGb3JtYXR0ZXIsXG59KSA9PiAoXG4gIDxkaXYgc3R5bGU9e3sgbWFyZ2luUmlnaHQ6IFwiMC41cmVtXCIgfX0+XG4gICAgPFRvb2x0aXBTbGlkZXJcbiAgICAgIHZlcnRpY2FsXG4gICAgICBtaW49e21pbn1cbiAgICAgIG1heD17bWF4fVxuICAgICAgc3RlcD17c3RlcH1cbiAgICAgIHJldmVyc2U9e3JldmVyc2V9XG4gICAgICBkZWZhdWx0VmFsdWU9e2RlZmF1bHRWYWx1ZX1cbiAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZSh0eXBlLCBpbmRleCl9XG4gICAgICBoYW5kbGVTdHlsZT17e1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9yLFxuICAgICAgICBib3JkZXJDb2xvcjogY29sb3IsXG4gICAgICAgIG9wYWNpdHk6IDEsXG4gICAgICB9fVxuICAgICAgdHJhY2tTdHlsZT17eyBiYWNrZ3JvdW5kQ29sb3I6IFwiIzg4OFwiLCB3aWR0aDogXCIycHhcIiB9fVxuICAgICAgcmFpbFN0eWxlPXt7IGJhY2tncm91bmRDb2xvcjogXCIjODg4XCIsIHdpZHRoOiBcIjJweFwiIH19XG4gICAgICB0aXBGb3JtYXR0ZXI9e3RpcEZvcm1hdHRlciB8fCAoKHZhbHVlKSA9PiB2YWx1ZSl9XG4gICAgLz5cbiAgPC9kaXY+XG4pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBSZWxhYmkgZnJvbSBcIi4uL3JlbGFiaVwiO1xuaW1wb3J0IENvbnRyb2xzIGZyb20gXCIuL0NvbnRyb2xzLmpzeFwiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7XG4gIGNvbnN0IFtyZWxhYmksIHNldFJlbGFiaV0gPSB1c2VTdGF0ZSgpO1xuICBjb25zdCByZWxhYmlSZWYgPSB1c2VSZWYoKTtcblxuICAvKipcbiAgICogSW5zdGFudGlhdGUgdGhlIFJlbGFiaSBnZW5lcmF0b3JcbiAgICovXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCFyZWxhYmkpIHtcbiAgICAgIGNvbnN0IHJlbGFiaUdlbmVyYXRvciA9IG5ldyBSZWxhYmkoe1xuICAgICAgICBzZXR0aW5nczoge1xuICAgICAgICAgIHNwZWVkOiAxLjAsXG4gICAgICAgICAgZmVlZGJhY2s6IDAuMixcbiAgICAgICAgfSxcbiAgICAgICAgd2F2ZXM6IFtcbiAgICAgICAgICB7IHNoYXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAwLjc1LCB3ZWlnaHQ6IDEgfSxcbiAgICAgICAgICB7IHNoYXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAxLjAsIHdlaWdodDogMSB9LFxuICAgICAgICAgIHsgc2hhcGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuNjE3LCB3ZWlnaHQ6IDEgfSxcbiAgICAgICAgICB7IHNoYXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAzLjE0MSwgd2VpZ2h0OiAxIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGJvdW5kczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxldmVsOiAtMC4yNSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiNmMzNcIixcbiAgICAgICAgICAgIHNvdW5kczogW3sgaW5zdHJ1bWVudDogXCJLaWNrXCIgfSwgeyBpbnN0cnVtZW50OiBcIlNuYXJlXCIgfV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogMC4yNSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiNmODNcIixcbiAgICAgICAgICAgIHNvdW5kczogW3sgaW5zdHJ1bWVudDogXCJIYXRcIiB9LCB7IGluc3RydW1lbnQ6IFwiUGVyY1wiIH1dLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgLy8ge1xuICAgICAgICAgIC8vICAgbGV2ZWw6IC0wLjI1LFxuICAgICAgICAgIC8vICAgY29sb3I6IFwiIzNiOFwiLFxuICAgICAgICAgIC8vICAgc291bmRzOiBbXG4gICAgICAgICAgLy8gICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiA0NDAgfSxcbiAgICAgICAgICAvLyAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiAzKSAvIDIgfSxcbiAgICAgICAgICAvLyAgIF0sXG4gICAgICAgICAgLy8gfSxcbiAgICAgICAgICAvLyB7XG4gICAgICAgICAgLy8gICBsZXZlbDogMC4yNSxcbiAgICAgICAgICAvLyAgIGNvbG9yOiBcIiMzNmZcIixcbiAgICAgICAgICAvLyAgIHNvdW5kczogW1xuICAgICAgICAgIC8vICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogKDQ0MCAqIDYpIC8gNSB9LFxuICAgICAgICAgIC8vICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogKDQ0MCAqIDYpIC8gNyB9LFxuICAgICAgICAgIC8vICAgXSxcbiAgICAgICAgICAvLyB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgICByZWxhYmlHZW5lcmF0b3Iuc3RhcnQoKTtcbiAgICAgIHNldFJlbGFiaShyZWxhYmlHZW5lcmF0b3IpO1xuICAgIH1cbiAgfSwgW3JlbGFiaV0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHJlbGFiaSAmJiByZWxhYmlSZWYuY3VycmVudCkge1xuICAgICAgcmVsYWJpLmNhbnZhcy5hcHBlbmRDYW52YXMocmVsYWJpUmVmLmN1cnJlbnQpO1xuICAgIH1cbiAgfSwgW3JlbGFiaSwgcmVsYWJpUmVmLmN1cnJlbnRdKTtcblxuICAvKipcbiAgICogUmVuZGVyXG4gICAqL1xuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIGhlaWdodDogXCIxMDAlXCIsXG4gICAgICAgIHdpZHRoOiBcIjEwMCVcIixcbiAgICAgICAgcGFkZGluZzogMCxcbiAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICBkaXNwbGF5OiBcImZsZXhcIixcbiAgICAgICAgZmxleERpcmVjdGlvbjogXCJjb2x1bW5cIixcbiAgICAgICAganVzdGlmeUNvbnRlbnQ6IFwiY2VudGVyXCIsXG4gICAgICB9fVxuICAgID5cbiAgICAgIDxkaXYgcmVmPXtyZWxhYmlSZWZ9IC8+XG4gICAgICA8Q29udHJvbHMgcmVsYWJpPXtyZWxhYml9IC8+XG4gICAgPC9kaXY+XG4gICk7XG59XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGNyZWF0ZVJvb3QgfSBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiO1xuaW1wb3J0IHsgcmVxdWVzdEF1ZGlvQ29udGV4dCwgcmFuZHJhbmdlIH0gZnJvbSBcIi4vbGliL3V0aWxcIjtcblxuaW1wb3J0IEFwcCBmcm9tIFwiLi91aS9BcHAuanN4XCI7XG5cbmRvY3VtZW50LmJvZHkuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCIjMTExXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gXCIjZmZmXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLm1hcmdpbiA9IDA7XG5kb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmcgPSAwO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbmRvY3VtZW50LmJvZHkuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbmRvY3VtZW50LmJvZHkuc3R5bGUuZm9udEZhbWlseSA9IFwiSGVsdmV0aWNhLCBBcmlhbFwiO1xuZG9jdW1lbnQuYm9keS5wYXJlbnROb2RlLnN0eWxlLm1hcmdpbiA9IDA7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUucGFkZGluZyA9IDA7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcblxucmVxdWVzdEF1ZGlvQ29udGV4dCgoKSA9PiB7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIGNvbnRhaW5lci5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbiAgY29udGFpbmVyLnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG4gIGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gXCJcIjtcbiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICBjb25zdCByb290ID0gY3JlYXRlUm9vdChjb250YWluZXIpO1xuICByb290LnJlbmRlcig8QXBwIC8+KTtcbn0pO1xuIl0sIm5hbWVzIjpbIlRvbmUiLCJTdGFydEF1ZGlvQ29udGV4dCIsImlzSXBob25lIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwibWF0Y2giLCJpc0lwYWQiLCJpc0FuZHJvaWQiLCJpc01vYmlsZSIsImlzRGVza3RvcCIsImRvY3VtZW50IiwiYm9keSIsImNsYXNzTGlzdCIsImFkZCIsImJyb3dzZXIiLCJjaG9pY2UiLCJhIiwiTWF0aCIsImZsb29yIiwicmFuZG9tIiwibGVuZ3RoIiwibW9kIiwibiIsIm0iLCJyYW5kIiwicmFuZGludCIsInJhbmRyYW5nZSIsImIiLCJyYW5kc2lnbiIsInJhbmRudWxsc2lnbiIsInIiLCJyZXF1ZXN0QXVkaW9Db250ZXh0IiwiZm4iLCJjb250YWluZXIiLCJjcmVhdGVFbGVtZW50IiwiYnV0dG9uIiwiaW5uZXJIVE1MIiwiT2JqZWN0IiwiYXNzaWduIiwic3R5bGUiLCJkaXNwbGF5IiwicG9zaXRpb24iLCJ3aWR0aCIsImhlaWdodCIsInpJbmRleCIsInRvcCIsImxlZnQiLCJiYWNrZ3JvdW5kQ29sb3IiLCJwYWRkaW5nIiwiY29sb3IiLCJmb250RmFtaWx5IiwiYm9yZGVyUmFkaXVzIiwidHJhbnNmb3JtIiwidGV4dEFsaWduIiwibGluZUhlaWdodCIsImN1cnNvciIsImFwcGVuZENoaWxkIiwic2V0Q29udGV4dCIsImNvbnRleHQiLCJvbiIsIm9uU3RhcnRlZCIsIl8iLCJyZW1vdmUiLCJOT1RFX1JBRElVUyIsIlJlbGFiaUNhbnZhcyIsIl9yZWYiLCJyZWxhYmkiLCJwYXJlbnQiLCJfY2xhc3NDYWxsQ2hlY2siLCJsYXN0RnJhbWUiLCJsYXN0QXBwZW5kVGltZSIsImxhc3RBcHBlbmRGcmFtZSIsInNwZWVkIiwidFplcm9PZmZzZXQiLCJhcHBlbmRDYW52YXMiLCJ2YWx1ZXMiLCJBcnJheSIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJmaWxsIiwibm90ZXMiLCJhcHBlbmQiLCJyZXNpemUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImNhbnZhcyIsImN0eCIsImdldENvbnRleHQiLCJfcmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiX3giLCJhcHBseSIsImFyZ3VtZW50cyIsInRvU3RyaW5nIiwiZnJhbWUiLCJfdGhpcyIsInBhaW50IiwiY2xlYXIiLCJjbGVhclJlY3QiLCJ0aW1lIiwiZmlsdGVyIiwiY29uY2F0Iiwic2xpY2UiLCJzb3J0IiwiZHJhd1JlbGFiaVdhdmUiLCJkcmF3Qm91bmRzIiwiZHJhd05vdGVzIiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJib3VuZHMiLCJfc3RlcCIsInMiLCJkb25lIiwiYm91bmQiLCJ5IiwiZ2V0V2F2ZUhlaWdodCIsImxldmVsIiwiYmVnaW5QYXRoIiwic2V0TGluZURhc2giLCJsaW5lV2lkdGgiLCJzdHJva2VTdHlsZSIsIm1vdmVUbyIsImxpbmVUbyIsInN0cm9rZSIsImVyciIsImUiLCJmIiwicG9pbnRDb3VudCIsImluZGV4IiwiZnJhbWVPZmZzZXQiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicG9pbnQiLCJfcG9pbnQiLCJfc2xpY2VkVG9BcnJheSIsInRpbWVPZmZzZXQiLCJ4IiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsIm5vdGUiLCJfbm90ZSIsImRpcmVjdGlvbiIsIm9wYWNpdHkiLCJhcmMiLCJQSSIsImZpbGxTdHlsZSIsImRlZmF1bHQiLCJjb21wcmVzc29yIiwiQ29tcHJlc3NvciIsImdhaW4iLCJHYWluIiwiY29ubmVjdCIsInRvRGVzdGluYXRpb24iLCJvdXRwdXQiLCJQTEFZRVJfQ09VTlQiLCJTYW1wbGVyIiwic2FtcGxlcyIsInRvbmFsIiwibWFwIiwiX3JlZjIiLCJzYW1wbGUiLCJfZXh0ZW5kcyIsIl9vYmplY3REZXN0cnVjdHVyaW5nRW1wdHkiLCJwbGF5ZXJzIiwiaSIsImxvY2F0aW9uIiwiaHJlZiIsInBsYXllciIsIlBsYXllciIsInVybCIsInJldHJpZ2dlciIsInBsYXliYWNrUmF0ZSIsInB1c2giLCJwbGF5Iiwib3B0aW9ucyIsInNvdW5kIiwiZnJlcXVlbmN5Iiwicm9vdCIsInN0YXJ0IiwiS2FsaW1iYSIsIkRydW1zIiwiS2ljayIsIlNuYXJlIiwiSGF0IiwiUGVyYyIsIkN5bWJhbCIsIlRvbSIsIkluc3RydW1lbnRzIiwiVFdPX1BJIiwiV0FWRV9TSEFQRVMiLCJzaW5lIiwiY29zIiwidHJpYW5nbGUiLCJhYnMiLCJzcXVhcmUiLCJzYXciLCJyZXZlcnNlX3NhdyIsIlJlbGFiaSIsIndhdmVzIiwic2V0dGluZ3MiLCJ1cGRhdGVUaW1lIiwic3RlcHMiLCJwcmV2aW91c1ZhbHVlIiwiY29uc29sZSIsImxvZyIsInN0b3AiLCJjbG9jayIsIkNsb2NrIiwiZ2VuZXJhdGUiLCJkaXNwb3NlIiwic3RlcCIsInByZXZpb3VzV2F2ZVZhbHVlIiwidG90YWxXZWlnaHQiLCJyZWR1Y2UiLCJzdW0iLCJ3YXZlIiwid2VpZ2h0Iiwic3RlcENvdW50Iiwid2F2ZU9mZnNldCIsIm9mZnNldCIsImZlZWRiYWNrIiwid2F2ZVZhbHVlIiwic2hhcGUiLCJib3VuZHNDb3VudCIsIm5vdGVDb3VudCIsIl92YWx1ZXMkc3RlcCIsInRyaWdnZXIiLCJzb3VuZHMiLCJpbnN0cnVtZW50IiwiUmVhY3QiLCJ1c2VDYWxsYmFjayIsInVzZVJlZiIsIlNsaWRlciIsIlRvb2x0aXBTbGlkZXIiLCJoYW5kbGVSZW5kZXIiLCJXQVZFX1NIQVBFX05BTUVTIiwiQ29udHJvbHMiLCJvbkNoYW5nZSIsInR5cGUiLCJleHAiLCJDb250cm9sUm93IiwiQ29udHJvbEJveCIsIkxhYmVsIiwiU2xpZGVyUm93IiwiQ29udHJvbFNsaWRlciIsInJlbCIsIm1pbiIsIm1heCIsInRpcEZvcm1hdHRlciIsImRlZmF1bHRWYWx1ZSIsInJldmVyc2UiLCJ0b0ZpeGVkIiwiaW5kZXhPZiIsImNoaWxkcmVuIiwiZmxleERpcmVjdGlvbiIsIm1hcmdpblRvcCIsIl9yZWYzIiwibWFyZ2luTGVmdCIsIl9yZWY0IiwiZmxleERpcmVjaXRvbiIsIl9yZWY1IiwiZm9udFNpemUiLCJfcmVmNiIsIm1hcmdpblJpZ2h0IiwidmVydGljYWwiLCJoYW5kbGVTdHlsZSIsImJvcmRlckNvbG9yIiwidHJhY2tTdHlsZSIsInJhaWxTdHlsZSIsInVzZVN0YXRlIiwidXNlRWZmZWN0IiwiQXBwIiwiX3VzZVN0YXRlIiwiX3VzZVN0YXRlMiIsInNldFJlbGFiaSIsInJlbGFiaVJlZiIsInJlbGFiaUdlbmVyYXRvciIsImN1cnJlbnQiLCJtYXJnaW4iLCJqdXN0aWZ5Q29udGVudCIsInJlZiIsImNyZWF0ZVJvb3QiLCJwYXJlbnROb2RlIiwicmVuZGVyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///905\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')},184:(module,exports)=>{eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\tvar nativeCodeString = '[native code]';\n\n\tfunction classNames() {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg)) {\n\t\t\t\tif (arg.length) {\n\t\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\t\tif (inner) {\n\t\t\t\t\t\tclasses.push(inner);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tif (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {\n\t\t\t\t\tclasses.push(arg.toString());\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif ( true && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (true) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n\t\t\treturn classNames;\n\t\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else {}\n}());\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTg0LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdCQUFnQjtBQUNoQjs7QUFFQTtBQUNBOztBQUVBLGtCQUFrQixzQkFBc0I7QUFDeEM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUssS0FBNkI7QUFDbEM7QUFDQTtBQUNBLEdBQUcsU0FBUyxJQUE0RTtBQUN4RjtBQUNBLEVBQUUsaUNBQXFCLEVBQUUsbUNBQUU7QUFDM0I7QUFDQSxHQUFHO0FBQUEsa0dBQUM7QUFDSixHQUFHLEtBQUssRUFFTjtBQUNGLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvY2xhc3NuYW1lcy9pbmRleC5qcz80ZDI2Il0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuXHRDb3B5cmlnaHQgKGMpIDIwMTggSmVkIFdhdHNvbi5cblx0TGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlIChNSVQpLCBzZWVcblx0aHR0cDovL2plZHdhdHNvbi5naXRodWIuaW8vY2xhc3NuYW1lc1xuKi9cbi8qIGdsb2JhbCBkZWZpbmUgKi9cblxuKGZ1bmN0aW9uICgpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBoYXNPd24gPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblx0dmFyIG5hdGl2ZUNvZGVTdHJpbmcgPSAnW25hdGl2ZSBjb2RlXSc7XG5cblx0ZnVuY3Rpb24gY2xhc3NOYW1lcygpIHtcblx0XHR2YXIgY2xhc3NlcyA9IFtdO1xuXG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBhcmcgPSBhcmd1bWVudHNbaV07XG5cdFx0XHRpZiAoIWFyZykgY29udGludWU7XG5cblx0XHRcdHZhciBhcmdUeXBlID0gdHlwZW9mIGFyZztcblxuXHRcdFx0aWYgKGFyZ1R5cGUgPT09ICdzdHJpbmcnIHx8IGFyZ1R5cGUgPT09ICdudW1iZXInKSB7XG5cdFx0XHRcdGNsYXNzZXMucHVzaChhcmcpO1xuXHRcdFx0fSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGFyZykpIHtcblx0XHRcdFx0aWYgKGFyZy5sZW5ndGgpIHtcblx0XHRcdFx0XHR2YXIgaW5uZXIgPSBjbGFzc05hbWVzLmFwcGx5KG51bGwsIGFyZyk7XG5cdFx0XHRcdFx0aWYgKGlubmVyKSB7XG5cdFx0XHRcdFx0XHRjbGFzc2VzLnB1c2goaW5uZXIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIGlmIChhcmdUeXBlID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRpZiAoYXJnLnRvU3RyaW5nICE9PSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nICYmICFhcmcudG9TdHJpbmcudG9TdHJpbmcoKS5pbmNsdWRlcygnW25hdGl2ZSBjb2RlXScpKSB7XG5cdFx0XHRcdFx0Y2xhc3Nlcy5wdXNoKGFyZy50b1N0cmluZygpKTtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGZvciAodmFyIGtleSBpbiBhcmcpIHtcblx0XHRcdFx0XHRpZiAoaGFzT3duLmNhbGwoYXJnLCBrZXkpICYmIGFyZ1trZXldKSB7XG5cdFx0XHRcdFx0XHRjbGFzc2VzLnB1c2goa2V5KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gY2xhc3Nlcy5qb2luKCcgJyk7XG5cdH1cblxuXHRpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlLmV4cG9ydHMpIHtcblx0XHRjbGFzc05hbWVzLmRlZmF1bHQgPSBjbGFzc05hbWVzO1xuXHRcdG1vZHVsZS5leHBvcnRzID0gY2xhc3NOYW1lcztcblx0fSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBkZWZpbmUuYW1kID09PSAnb2JqZWN0JyAmJiBkZWZpbmUuYW1kKSB7XG5cdFx0Ly8gcmVnaXN0ZXIgYXMgJ2NsYXNzbmFtZXMnLCBjb25zaXN0ZW50IHdpdGggbnBtIHBhY2thZ2UgbmFtZVxuXHRcdGRlZmluZSgnY2xhc3NuYW1lcycsIFtdLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gY2xhc3NOYW1lcztcblx0XHR9KTtcblx0fSBlbHNlIHtcblx0XHR3aW5kb3cuY2xhc3NOYW1lcyA9IGNsYXNzTmFtZXM7XG5cdH1cbn0oKSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///184\n")},687:(module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(537);\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(645);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ".rc-slider {\\n position: relative;\\n width: 100%;\\n height: 14px;\\n padding: 5px 0;\\n border-radius: 6px;\\n touch-action: none;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-rail {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background-color: #e9e9e9;\\n border-radius: 6px;\\n}\\n.rc-slider-track {\\n position: absolute;\\n height: 4px;\\n background-color: #abe2fb;\\n border-radius: 6px;\\n}\\n.rc-slider-handle {\\n position: absolute;\\n width: 14px;\\n height: 14px;\\n margin-top: -5px;\\n background-color: #fff;\\n border: solid 2px #96dbfa;\\n border-radius: 50%;\\n cursor: pointer;\\n cursor: -webkit-grab;\\n cursor: grab;\\n opacity: 0.8;\\n touch-action: pan-x;\\n}\\n.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {\\n border-color: #57c5f7;\\n box-shadow: 0 0 0 5px #96dbfa;\\n}\\n.rc-slider-handle:focus {\\n outline: none;\\n box-shadow: none;\\n}\\n.rc-slider-handle:focus-visible {\\n border-color: #2db7f5;\\n box-shadow: 0 0 0 3px #96dbfa;\\n}\\n.rc-slider-handle-click-focused:focus {\\n border-color: #96dbfa;\\n box-shadow: unset;\\n}\\n.rc-slider-handle:hover {\\n border-color: #57c5f7;\\n}\\n.rc-slider-handle:active {\\n border-color: #57c5f7;\\n box-shadow: 0 0 5px #57c5f7;\\n cursor: -webkit-grabbing;\\n cursor: grabbing;\\n}\\n.rc-slider-mark {\\n position: absolute;\\n top: 18px;\\n left: 0;\\n width: 100%;\\n font-size: 12px;\\n}\\n.rc-slider-mark-text {\\n position: absolute;\\n display: inline-block;\\n color: #999;\\n text-align: center;\\n vertical-align: middle;\\n cursor: pointer;\\n}\\n.rc-slider-mark-text-active {\\n color: #666;\\n}\\n.rc-slider-step {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background: transparent;\\n pointer-events: none;\\n}\\n.rc-slider-dot {\\n position: absolute;\\n bottom: -2px;\\n width: 8px;\\n height: 8px;\\n vertical-align: middle;\\n background-color: #fff;\\n border: 2px solid #e9e9e9;\\n border-radius: 50%;\\n cursor: pointer;\\n}\\n.rc-slider-dot-active {\\n border-color: #96dbfa;\\n}\\n.rc-slider-dot-reverse {\\n margin-right: -4px;\\n}\\n.rc-slider-disabled {\\n background-color: #e9e9e9;\\n}\\n.rc-slider-disabled .rc-slider-track {\\n background-color: #ccc;\\n}\\n.rc-slider-disabled .rc-slider-handle,\\n.rc-slider-disabled .rc-slider-dot {\\n background-color: #fff;\\n border-color: #ccc;\\n box-shadow: none;\\n cursor: not-allowed;\\n}\\n.rc-slider-disabled .rc-slider-mark-text,\\n.rc-slider-disabled .rc-slider-dot {\\n cursor: not-allowed !important;\\n}\\n.rc-slider-vertical {\\n width: 14px;\\n height: 100%;\\n padding: 0 5px;\\n}\\n.rc-slider-vertical .rc-slider-rail {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-track {\\n bottom: 0;\\n left: 5px;\\n width: 4px;\\n}\\n.rc-slider-vertical .rc-slider-handle {\\n margin-top: 0;\\n margin-left: -5px;\\n touch-action: pan-y;\\n}\\n.rc-slider-vertical .rc-slider-mark {\\n top: 0;\\n left: 18px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-step {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-dot {\\n margin-left: -2px;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,\\n.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {\\n animation-name: rcSliderTooltipZoomDownIn;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {\\n animation-name: rcSliderTooltipZoomDownOut;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n transform: scale(0, 0);\\n animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);\\n}\\n@keyframes rcSliderTooltipZoomDownIn {\\n 0% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n 100% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n}\\n@keyframes rcSliderTooltipZoomDownOut {\\n 0% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n 100% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n}\\n.rc-slider-tooltip {\\n position: absolute;\\n top: -9999px;\\n left: -9999px;\\n visibility: visible;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip-hidden {\\n display: none;\\n}\\n.rc-slider-tooltip-placement-top {\\n padding: 4px 0 8px 0;\\n}\\n.rc-slider-tooltip-inner {\\n min-width: 24px;\\n height: 24px;\\n padding: 6px 2px;\\n color: #fff;\\n font-size: 12px;\\n line-height: 1;\\n text-align: center;\\n text-decoration: none;\\n background-color: #6c6c6c;\\n border-radius: 6px;\\n box-shadow: 0 0 4px #d9d9d9;\\n}\\n.rc-slider-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {\\n bottom: 4px;\\n left: 50%;\\n margin-left: -4px;\\n border-width: 4px 4px 0;\\n border-top-color: #6c6c6c;\\n}\\n", "",{"version":3,"sources":["webpack://./node_modules/rc-slider/assets/index.css"],"names":[],"mappings":"AAAA;EACE,kBAAkB;EAClB,WAAW;EACX,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,kBAAkB;EAClB,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,WAAW;EACX,yBAAyB;EACzB,kBAAkB;AACpB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,yBAAyB;EACzB,kBAAkB;AACpB;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,YAAY;EACZ,gBAAgB;EAChB,sBAAsB;EACtB,yBAAyB;EACzB,kBAAkB;EAClB,eAAe;EACf,oBAAoB;EACpB,YAAY;EACZ,YAAY;EACZ,mBAAmB;AACrB;AACA;EACE,qBAAqB;EACrB,6BAA6B;AAC/B;AACA;EACE,aAAa;EACb,gBAAgB;AAClB;AACA;EACE,qBAAqB;EACrB,6BAA6B;AAC/B;AACA;EACE,qBAAqB;EACrB,iBAAiB;AACnB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,qBAAqB;EACrB,2BAA2B;EAC3B,wBAAwB;EACxB,gBAAgB;AAClB;AACA;EACE,kBAAkB;EAClB,SAAS;EACT,OAAO;EACP,WAAW;EACX,eAAe;AACjB;AACA;EACE,kBAAkB;EAClB,qBAAqB;EACrB,WAAW;EACX,kBAAkB;EAClB,sBAAsB;EACtB,eAAe;AACjB;AACA;EACE,WAAW;AACb;AACA;EACE,kBAAkB;EAClB,WAAW;EACX,WAAW;EACX,uBAAuB;EACvB,oBAAoB;AACtB;AACA;EACE,kBAAkB;EAClB,YAAY;EACZ,UAAU;EACV,WAAW;EACX,sBAAsB;EACtB,sBAAsB;EACtB,yBAAyB;EACzB,kBAAkB;EAClB,eAAe;AACjB;AACA;EACE,qBAAqB;AACvB;AACA;EACE,kBAAkB;AACpB;AACA;EACE,yBAAyB;AAC3B;AACA;EACE,sBAAsB;AACxB;AACA;;EAEE,sBAAsB;EACtB,kBAAkB;EAClB,gBAAgB;EAChB,mBAAmB;AACrB;AACA;;EAEE,8BAA8B;AAChC;AACA;EACE,WAAW;EACX,YAAY;EACZ,cAAc;AAChB;AACA;EACE,UAAU;EACV,YAAY;AACd;AACA;EACE,SAAS;EACT,SAAS;EACT,UAAU;AACZ;AACA;EACE,aAAa;EACb,iBAAiB;EACjB,mBAAmB;AACrB;AACA;EACE,MAAM;EACN,UAAU;EACV,YAAY;AACd;AACA;EACE,UAAU;EACV,YAAY;AACd;AACA;EACE,iBAAiB;AACnB;AACA;;EAEE,yBAAyB;EACzB,wBAAwB;EACxB,yBAAyB;EACzB,4BAA4B;AAC9B;AACA;EACE,yBAAyB;EACzB,wBAAwB;EACxB,yBAAyB;EACzB,4BAA4B;AAC9B;AACA;;EAEE,yCAAyC;EACzC,6BAA6B;AAC/B;AACA;EACE,0CAA0C;EAC1C,6BAA6B;AAC/B;AACA;;EAEE,sBAAsB;EACtB,yDAAyD;AAC3D;AACA;EACE,iEAAiE;AACnE;AACA;EACE;IACE,sBAAsB;IACtB,0BAA0B;IAC1B,UAAU;EACZ;EACA;IACE,sBAAsB;IACtB,0BAA0B;EAC5B;AACF;AACA;EACE;IACE,sBAAsB;IACtB,0BAA0B;EAC5B;EACA;IACE,sBAAsB;IACtB,0BAA0B;IAC1B,UAAU;EACZ;AACF;AACA;EACE,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,sBAAsB;EACtB,6CAA6C;AAC/C;AACA;EACE,aAAa;AACf;AACA;EACE,oBAAoB;AACtB;AACA;EACE,eAAe;EACf,YAAY;EACZ,gBAAgB;EAChB,WAAW;EACX,eAAe;EACf,cAAc;EACd,kBAAkB;EAClB,qBAAqB;EACrB,yBAAyB;EACzB,kBAAkB;EAClB,2BAA2B;AAC7B;AACA;EACE,kBAAkB;EAClB,QAAQ;EACR,SAAS;EACT,yBAAyB;EACzB,mBAAmB;AACrB;AACA;EACE,WAAW;EACX,SAAS;EACT,iBAAiB;EACjB,uBAAuB;EACvB,yBAAyB;AAC3B","sourcesContent":[".rc-slider {\\n position: relative;\\n width: 100%;\\n height: 14px;\\n padding: 5px 0;\\n border-radius: 6px;\\n touch-action: none;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-rail {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background-color: #e9e9e9;\\n border-radius: 6px;\\n}\\n.rc-slider-track {\\n position: absolute;\\n height: 4px;\\n background-color: #abe2fb;\\n border-radius: 6px;\\n}\\n.rc-slider-handle {\\n position: absolute;\\n width: 14px;\\n height: 14px;\\n margin-top: -5px;\\n background-color: #fff;\\n border: solid 2px #96dbfa;\\n border-radius: 50%;\\n cursor: pointer;\\n cursor: -webkit-grab;\\n cursor: grab;\\n opacity: 0.8;\\n touch-action: pan-x;\\n}\\n.rc-slider-handle-dragging.rc-slider-handle-dragging.rc-slider-handle-dragging {\\n border-color: #57c5f7;\\n box-shadow: 0 0 0 5px #96dbfa;\\n}\\n.rc-slider-handle:focus {\\n outline: none;\\n box-shadow: none;\\n}\\n.rc-slider-handle:focus-visible {\\n border-color: #2db7f5;\\n box-shadow: 0 0 0 3px #96dbfa;\\n}\\n.rc-slider-handle-click-focused:focus {\\n border-color: #96dbfa;\\n box-shadow: unset;\\n}\\n.rc-slider-handle:hover {\\n border-color: #57c5f7;\\n}\\n.rc-slider-handle:active {\\n border-color: #57c5f7;\\n box-shadow: 0 0 5px #57c5f7;\\n cursor: -webkit-grabbing;\\n cursor: grabbing;\\n}\\n.rc-slider-mark {\\n position: absolute;\\n top: 18px;\\n left: 0;\\n width: 100%;\\n font-size: 12px;\\n}\\n.rc-slider-mark-text {\\n position: absolute;\\n display: inline-block;\\n color: #999;\\n text-align: center;\\n vertical-align: middle;\\n cursor: pointer;\\n}\\n.rc-slider-mark-text-active {\\n color: #666;\\n}\\n.rc-slider-step {\\n position: absolute;\\n width: 100%;\\n height: 4px;\\n background: transparent;\\n pointer-events: none;\\n}\\n.rc-slider-dot {\\n position: absolute;\\n bottom: -2px;\\n width: 8px;\\n height: 8px;\\n vertical-align: middle;\\n background-color: #fff;\\n border: 2px solid #e9e9e9;\\n border-radius: 50%;\\n cursor: pointer;\\n}\\n.rc-slider-dot-active {\\n border-color: #96dbfa;\\n}\\n.rc-slider-dot-reverse {\\n margin-right: -4px;\\n}\\n.rc-slider-disabled {\\n background-color: #e9e9e9;\\n}\\n.rc-slider-disabled .rc-slider-track {\\n background-color: #ccc;\\n}\\n.rc-slider-disabled .rc-slider-handle,\\n.rc-slider-disabled .rc-slider-dot {\\n background-color: #fff;\\n border-color: #ccc;\\n box-shadow: none;\\n cursor: not-allowed;\\n}\\n.rc-slider-disabled .rc-slider-mark-text,\\n.rc-slider-disabled .rc-slider-dot {\\n cursor: not-allowed !important;\\n}\\n.rc-slider-vertical {\\n width: 14px;\\n height: 100%;\\n padding: 0 5px;\\n}\\n.rc-slider-vertical .rc-slider-rail {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-track {\\n bottom: 0;\\n left: 5px;\\n width: 4px;\\n}\\n.rc-slider-vertical .rc-slider-handle {\\n margin-top: 0;\\n margin-left: -5px;\\n touch-action: pan-y;\\n}\\n.rc-slider-vertical .rc-slider-mark {\\n top: 0;\\n left: 18px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-step {\\n width: 4px;\\n height: 100%;\\n}\\n.rc-slider-vertical .rc-slider-dot {\\n margin-left: -2px;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n display: block !important;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-play-state: paused;\\n}\\n.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,\\n.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {\\n animation-name: rcSliderTooltipZoomDownIn;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {\\n animation-name: rcSliderTooltipZoomDownOut;\\n animation-play-state: running;\\n}\\n.rc-slider-tooltip-zoom-down-enter,\\n.rc-slider-tooltip-zoom-down-appear {\\n transform: scale(0, 0);\\n animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);\\n}\\n.rc-slider-tooltip-zoom-down-leave {\\n animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);\\n}\\n@keyframes rcSliderTooltipZoomDownIn {\\n 0% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n 100% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n}\\n@keyframes rcSliderTooltipZoomDownOut {\\n 0% {\\n transform: scale(1, 1);\\n transform-origin: 50% 100%;\\n }\\n 100% {\\n transform: scale(0, 0);\\n transform-origin: 50% 100%;\\n opacity: 0;\\n }\\n}\\n.rc-slider-tooltip {\\n position: absolute;\\n top: -9999px;\\n left: -9999px;\\n visibility: visible;\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip * {\\n box-sizing: border-box;\\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\\n}\\n.rc-slider-tooltip-hidden {\\n display: none;\\n}\\n.rc-slider-tooltip-placement-top {\\n padding: 4px 0 8px 0;\\n}\\n.rc-slider-tooltip-inner {\\n min-width: 24px;\\n height: 24px;\\n padding: 6px 2px;\\n color: #fff;\\n font-size: 12px;\\n line-height: 1;\\n text-align: center;\\n text-decoration: none;\\n background-color: #6c6c6c;\\n border-radius: 6px;\\n box-shadow: 0 0 4px #d9d9d9;\\n}\\n.rc-slider-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {\\n bottom: 4px;\\n left: 50%;\\n margin-left: -4px;\\n border-width: 4px 4px 0;\\n border-top-color: #6c6c6c;\\n}\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LFdBQVcsVUFBVSxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxhQUFhLGFBQWEsV0FBVyxZQUFZLFdBQVcsVUFBVSxZQUFZLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxLQUFLLFVBQVUsWUFBWSxNQUFNLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksYUFBYSxhQUFhLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFVBQVUsVUFBVSxNQUFNLEtBQUssWUFBWSxhQUFhLFdBQVcsWUFBWSxhQUFhLFdBQVcsTUFBTSxLQUFLLFVBQVUsS0FBSyxLQUFLLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxNQUFNLEtBQUssWUFBWSxXQUFXLFVBQVUsVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLFdBQVcsTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxLQUFLLFlBQVksTUFBTSxNQUFNLFlBQVksYUFBYSxhQUFhLGFBQWEsTUFBTSxNQUFNLFlBQVksTUFBTSxLQUFLLFVBQVUsVUFBVSxVQUFVLE1BQU0sS0FBSyxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxVQUFVLEtBQUssS0FBSyxVQUFVLFlBQVksYUFBYSxNQUFNLEtBQUssVUFBVSxVQUFVLFVBQVUsS0FBSyxLQUFLLFVBQVUsVUFBVSxLQUFLLEtBQUssWUFBWSxNQUFNLE1BQU0sWUFBWSxhQUFhLGFBQWEsYUFBYSxNQUFNLEtBQUssWUFBWSxhQUFhLGFBQWEsYUFBYSxNQUFNLE1BQU0sWUFBWSxhQUFhLE1BQU0sS0FBSyxZQUFZLGFBQWEsTUFBTSxNQUFNLFlBQVksYUFBYSxNQUFNLEtBQUssWUFBWSxNQUFNLEtBQUssS0FBSyxZQUFZLGFBQWEsV0FBVyxLQUFLLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxLQUFLLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxZQUFZLGFBQWEsV0FBVyxLQUFLLEtBQUssS0FBSyxZQUFZLFdBQVcsVUFBVSxZQUFZLGFBQWEsYUFBYSxNQUFNLEtBQUssWUFBWSxhQUFhLE1BQU0sS0FBSyxVQUFVLEtBQUssS0FBSyxZQUFZLE1BQU0sS0FBSyxVQUFVLFVBQVUsWUFBWSxXQUFXLFVBQVUsVUFBVSxZQUFZLGFBQWEsYUFBYSxhQUFhLGFBQWEsTUFBTSxLQUFLLFlBQVksV0FBVyxVQUFVLFlBQVksYUFBYSxNQUFNLEtBQUssVUFBVSxVQUFVLFlBQVksYUFBYSxhQUFhLHNDQUFzQyx1QkFBdUIsZ0JBQWdCLGlCQUFpQixtQkFBbUIsdUJBQXVCLHVCQUF1QiwyQkFBMkIsa0RBQWtELEdBQUcsZ0JBQWdCLDJCQUEyQixrREFBa0QsR0FBRyxtQkFBbUIsdUJBQXVCLGdCQUFnQixnQkFBZ0IsOEJBQThCLHVCQUF1QixHQUFHLG9CQUFvQix1QkFBdUIsZ0JBQWdCLDhCQUE4Qix1QkFBdUIsR0FBRyxxQkFBcUIsdUJBQXVCLGdCQUFnQixpQkFBaUIscUJBQXFCLDJCQUEyQiw4QkFBOEIsdUJBQXVCLG9CQUFvQix5QkFBeUIsaUJBQWlCLGlCQUFpQix3QkFBd0IsR0FBRyxrRkFBa0YsMEJBQTBCLGtDQUFrQyxHQUFHLDJCQUEyQixrQkFBa0IscUJBQXFCLEdBQUcsbUNBQW1DLDBCQUEwQixrQ0FBa0MsR0FBRyx5Q0FBeUMsMEJBQTBCLHNCQUFzQixHQUFHLDJCQUEyQiwwQkFBMEIsR0FBRyw0QkFBNEIsMEJBQTBCLGdDQUFnQyw2QkFBNkIscUJBQXFCLEdBQUcsbUJBQW1CLHVCQUF1QixjQUFjLFlBQVksZ0JBQWdCLG9CQUFvQixHQUFHLHdCQUF3Qix1QkFBdUIsMEJBQTBCLGdCQUFnQix1QkFBdUIsMkJBQTJCLG9CQUFvQixHQUFHLCtCQUErQixnQkFBZ0IsR0FBRyxtQkFBbUIsdUJBQXVCLGdCQUFnQixnQkFBZ0IsNEJBQTRCLHlCQUF5QixHQUFHLGtCQUFrQix1QkFBdUIsaUJBQWlCLGVBQWUsZ0JBQWdCLDJCQUEyQiwyQkFBMkIsOEJBQThCLHVCQUF1QixvQkFBb0IsR0FBRyx5QkFBeUIsMEJBQTBCLEdBQUcsMEJBQTBCLHVCQUF1QixHQUFHLHVCQUF1Qiw4QkFBOEIsR0FBRyx3Q0FBd0MsMkJBQTJCLEdBQUcsOEVBQThFLDJCQUEyQix1QkFBdUIscUJBQXFCLHdCQUF3QixHQUFHLGlGQUFpRixtQ0FBbUMsR0FBRyx1QkFBdUIsZ0JBQWdCLGlCQUFpQixtQkFBbUIsR0FBRyx1Q0FBdUMsZUFBZSxpQkFBaUIsR0FBRyx3Q0FBd0MsY0FBYyxjQUFjLGVBQWUsR0FBRyx5Q0FBeUMsa0JBQWtCLHNCQUFzQix3QkFBd0IsR0FBRyx1Q0FBdUMsV0FBVyxlQUFlLGlCQUFpQixHQUFHLHVDQUF1QyxlQUFlLGlCQUFpQixHQUFHLHNDQUFzQyxzQkFBc0IsR0FBRyw0RUFBNEUsOEJBQThCLDZCQUE2Qiw4QkFBOEIsaUNBQWlDLEdBQUcsc0NBQXNDLDhCQUE4Qiw2QkFBNkIsOEJBQThCLGlDQUFpQyxHQUFHLCtKQUErSiw4Q0FBOEMsa0NBQWtDLEdBQUcsK0VBQStFLCtDQUErQyxrQ0FBa0MsR0FBRyw0RUFBNEUsMkJBQTJCLDhEQUE4RCxHQUFHLHNDQUFzQyxzRUFBc0UsR0FBRyx3Q0FBd0MsUUFBUSw2QkFBNkIsaUNBQWlDLGlCQUFpQixLQUFLLFVBQVUsNkJBQTZCLGlDQUFpQyxLQUFLLEdBQUcseUNBQXlDLFFBQVEsNkJBQTZCLGlDQUFpQyxLQUFLLFVBQVUsNkJBQTZCLGlDQUFpQyxpQkFBaUIsS0FBSyxHQUFHLHNCQUFzQix1QkFBdUIsaUJBQWlCLGtCQUFrQix3QkFBd0IsMkJBQTJCLGtEQUFrRCxHQUFHLHdCQUF3QiwyQkFBMkIsa0RBQWtELEdBQUcsNkJBQTZCLGtCQUFrQixHQUFHLG9DQUFvQyx5QkFBeUIsR0FBRyw0QkFBNEIsb0JBQW9CLGlCQUFpQixxQkFBcUIsZ0JBQWdCLG9CQUFvQixtQkFBbUIsdUJBQXVCLDBCQUEwQiw4QkFBOEIsdUJBQXVCLGdDQUFnQyxHQUFHLDRCQUE0Qix1QkFBdUIsYUFBYSxjQUFjLDhCQUE4Qix3QkFBd0IsR0FBRyw2REFBNkQsZ0JBQWdCLGNBQWMsc0JBQXNCLDRCQUE0Qiw4QkFBOEIsR0FBRyxxQkFBcUI7QUFDLy9hO0FBQ0EsaUVBQWUsdUJBQXVCLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtc2xpZGVyL2Fzc2V0cy9pbmRleC5jc3M/YTA3YSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBJbXBvcnRzXG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qc1wiO1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyBmcm9tIFwiLi4vLi4vY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG4vLyBNb2R1bGVcbl9fX0NTU19MT0FERVJfRVhQT1JUX19fLnB1c2goW21vZHVsZS5pZCwgXCIucmMtc2xpZGVyIHtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgaGVpZ2h0OiAxNHB4O1xcbiAgcGFkZGluZzogNXB4IDA7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICB0b3VjaC1hY3Rpb246IG5vbmU7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiByZ2JhKDAsIDAsIDAsIDApO1xcbn1cXG4ucmMtc2xpZGVyICoge1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci1yYWlsIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHdpZHRoOiAxMDAlO1xcbiAgaGVpZ2h0OiA0cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZTllOWU5O1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbn1cXG4ucmMtc2xpZGVyLXRyYWNrIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGhlaWdodDogNHB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2FiZTJmYjtcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDE0cHg7XFxuICBoZWlnaHQ6IDE0cHg7XFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2ZmZjtcXG4gIGJvcmRlcjogc29saWQgMnB4ICM5NmRiZmE7XFxuICBib3JkZXItcmFkaXVzOiA1MCU7XFxuICBjdXJzb3I6IHBvaW50ZXI7XFxuICBjdXJzb3I6IC13ZWJraXQtZ3JhYjtcXG4gIGN1cnNvcjogZ3JhYjtcXG4gIG9wYWNpdHk6IDAuODtcXG4gIHRvdWNoLWFjdGlvbjogcGFuLXg7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlLWRyYWdnaW5nLnJjLXNsaWRlci1oYW5kbGUtZHJhZ2dpbmcucmMtc2xpZGVyLWhhbmRsZS1kcmFnZ2luZyB7XFxuICBib3JkZXItY29sb3I6ICM1N2M1Zjc7XFxuICBib3gtc2hhZG93OiAwIDAgMCA1cHggIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6Zm9jdXMge1xcbiAgb3V0bGluZTogbm9uZTtcXG4gIGJveC1zaGFkb3c6IG5vbmU7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlOmZvY3VzLXZpc2libGUge1xcbiAgYm9yZGVyLWNvbG9yOiAjMmRiN2Y1O1xcbiAgYm94LXNoYWRvdzogMCAwIDAgM3B4ICM5NmRiZmE7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlLWNsaWNrLWZvY3VzZWQ6Zm9jdXMge1xcbiAgYm9yZGVyLWNvbG9yOiAjOTZkYmZhO1xcbiAgYm94LXNoYWRvdzogdW5zZXQ7XFxufVxcbi5yYy1zbGlkZXItaGFuZGxlOmhvdmVyIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6YWN0aXZlIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG4gIGJveC1zaGFkb3c6IDAgMCA1cHggIzU3YzVmNztcXG4gIGN1cnNvcjogLXdlYmtpdC1ncmFiYmluZztcXG4gIGN1cnNvcjogZ3JhYmJpbmc7XFxufVxcbi5yYy1zbGlkZXItbWFyayB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IDE4cHg7XFxuICBsZWZ0OiAwO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBmb250LXNpemU6IDEycHg7XFxufVxcbi5yYy1zbGlkZXItbWFyay10ZXh0IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcXG4gIGNvbG9yOiAjOTk5O1xcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLnJjLXNsaWRlci1tYXJrLXRleHQtYWN0aXZlIHtcXG4gIGNvbG9yOiAjNjY2O1xcbn1cXG4ucmMtc2xpZGVyLXN0ZXAge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDRweDtcXG4gIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XFxufVxcbi5yYy1zbGlkZXItZG90IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIGJvdHRvbTogLTJweDtcXG4gIHdpZHRoOiA4cHg7XFxuICBoZWlnaHQ6IDhweDtcXG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyOiAycHggc29saWQgI2U5ZTllOTtcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG59XFxuLnJjLXNsaWRlci1kb3QtYWN0aXZlIHtcXG4gIGJvcmRlci1jb2xvcjogIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1kb3QtcmV2ZXJzZSB7XFxuICBtYXJnaW4tcmlnaHQ6IC00cHg7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2U5ZTllOTtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLXRyYWNrIHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNjY2M7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQgLnJjLXNsaWRlci1oYW5kbGUsXFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWRvdCB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyLWNvbG9yOiAjY2NjO1xcbiAgYm94LXNoYWRvdzogbm9uZTtcXG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XFxufVxcbi5yYy1zbGlkZXItZGlzYWJsZWQgLnJjLXNsaWRlci1tYXJrLXRleHQsXFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWRvdCB7XFxuICBjdXJzb3I6IG5vdC1hbGxvd2VkICFpbXBvcnRhbnQ7XFxufVxcbi5yYy1zbGlkZXItdmVydGljYWwge1xcbiAgd2lkdGg6IDE0cHg7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBwYWRkaW5nOiAwIDVweDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXJhaWwge1xcbiAgd2lkdGg6IDRweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXRyYWNrIHtcXG4gIGJvdHRvbTogMDtcXG4gIGxlZnQ6IDVweDtcXG4gIHdpZHRoOiA0cHg7XFxufVxcbi5yYy1zbGlkZXItdmVydGljYWwgLnJjLXNsaWRlci1oYW5kbGUge1xcbiAgbWFyZ2luLXRvcDogMDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgdG91Y2gtYWN0aW9uOiBwYW4teTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLW1hcmsge1xcbiAgdG9wOiAwO1xcbiAgbGVmdDogMThweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLXN0ZXAge1xcbiAgd2lkdGg6IDRweDtcXG4gIGhlaWdodDogMTAwJTtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLWRvdCB7XFxuICBtYXJnaW4tbGVmdDogLTJweDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1lbnRlcixcXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhciB7XFxuICBkaXNwbGF5OiBibG9jayAhaW1wb3J0YW50O1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAwLjNzO1xcbiAgYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUge1xcbiAgZGlzcGxheTogYmxvY2sgIWltcG9ydGFudDtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1lbnRlci1hY3RpdmUsXFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1hcHBlYXIucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhci1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duSW47XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcnVubmluZztcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZS5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUtYWN0aXZlIHtcXG4gIGFuaW1hdGlvbi1uYW1lOiByY1NsaWRlclRvb2x0aXBab29tRG93bk91dDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLFxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyIHtcXG4gIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tbGVhdmUge1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuNzU1LCAwLjA1LCAwLjg1NSwgMC4wNik7XFxufVxcbkBrZXlmcmFtZXMgcmNTbGlkZXJUb29sdGlwWm9vbURvd25JbiB7XFxuICAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSAxMDAlO1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgfVxcbiAgMTAwJSB7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSAxMDAlO1xcbiAgfVxcbn1cXG5Aa2V5ZnJhbWVzIHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duT3V0IHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICAgIG9wYWNpdHk6IDA7XFxuICB9XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB0b3A6IC05OTk5cHg7XFxuICBsZWZ0OiAtOTk5OXB4O1xcbiAgdmlzaWJpbGl0eTogdmlzaWJsZTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcCAqIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1oaWRkZW4ge1xcbiAgZGlzcGxheTogbm9uZTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXBsYWNlbWVudC10b3Age1xcbiAgcGFkZGluZzogNHB4IDAgOHB4IDA7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1pbm5lciB7XFxuICBtaW4td2lkdGg6IDI0cHg7XFxuICBoZWlnaHQ6IDI0cHg7XFxuICBwYWRkaW5nOiA2cHggMnB4O1xcbiAgY29sb3I6ICNmZmY7XFxuICBmb250LXNpemU6IDEycHg7XFxuICBsaW5lLWhlaWdodDogMTtcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICM2YzZjNmM7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICBib3gtc2hhZG93OiAwIDAgNHB4ICNkOWQ5ZDk7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1hcnJvdyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMDtcXG4gIGhlaWdodDogMDtcXG4gIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XFxuICBib3JkZXItc3R5bGU6IHNvbGlkO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtc2xpZGVyLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiA0cHg7XFxuICBsZWZ0OiA1MCU7XFxuICBtYXJnaW4tbGVmdDogLTRweDtcXG4gIGJvcmRlci13aWR0aDogNHB4IDRweCAwO1xcbiAgYm9yZGVyLXRvcC1jb2xvcjogIzZjNmM2YztcXG59XFxuXCIsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vbm9kZV9tb2R1bGVzL3JjLXNsaWRlci9hc3NldHMvaW5kZXguY3NzXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCJBQUFBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxZQUFZO0VBQ1osY0FBYztFQUNkLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsc0JBQXNCO0VBQ3RCLDZDQUE2QztBQUMvQztBQUNBO0VBQ0Usc0JBQXNCO0VBQ3RCLDZDQUE2QztBQUMvQztBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxXQUFXO0VBQ1gseUJBQXlCO0VBQ3pCLGtCQUFrQjtBQUNwQjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCx5QkFBeUI7RUFDekIsa0JBQWtCO0FBQ3BCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIsV0FBVztFQUNYLFlBQVk7RUFDWixnQkFBZ0I7RUFDaEIsc0JBQXNCO0VBQ3RCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsZUFBZTtFQUNmLG9CQUFvQjtFQUNwQixZQUFZO0VBQ1osWUFBWTtFQUNaLG1CQUFtQjtBQUNyQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLDZCQUE2QjtBQUMvQjtBQUNBO0VBQ0UsYUFBYTtFQUNiLGdCQUFnQjtBQUNsQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLDZCQUE2QjtBQUMvQjtBQUNBO0VBQ0UscUJBQXFCO0VBQ3JCLGlCQUFpQjtBQUNuQjtBQUNBO0VBQ0UscUJBQXFCO0FBQ3ZCO0FBQ0E7RUFDRSxxQkFBcUI7RUFDckIsMkJBQTJCO0VBQzNCLHdCQUF3QjtFQUN4QixnQkFBZ0I7QUFDbEI7QUFDQTtFQUNFLGtCQUFrQjtFQUNsQixTQUFTO0VBQ1QsT0FBTztFQUNQLFdBQVc7RUFDWCxlQUFlO0FBQ2pCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIscUJBQXFCO0VBQ3JCLFdBQVc7RUFDWCxrQkFBa0I7RUFDbEIsc0JBQXNCO0VBQ3RCLGVBQWU7QUFDakI7QUFDQTtFQUNFLFdBQVc7QUFDYjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFdBQVc7RUFDWCxXQUFXO0VBQ1gsdUJBQXVCO0VBQ3ZCLG9CQUFvQjtBQUN0QjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFlBQVk7RUFDWixVQUFVO0VBQ1YsV0FBVztFQUNYLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIseUJBQXlCO0VBQ3pCLGtCQUFrQjtFQUNsQixlQUFlO0FBQ2pCO0FBQ0E7RUFDRSxxQkFBcUI7QUFDdkI7QUFDQTtFQUNFLGtCQUFrQjtBQUNwQjtBQUNBO0VBQ0UseUJBQXlCO0FBQzNCO0FBQ0E7RUFDRSxzQkFBc0I7QUFDeEI7QUFDQTs7RUFFRSxzQkFBc0I7RUFDdEIsa0JBQWtCO0VBQ2xCLGdCQUFnQjtFQUNoQixtQkFBbUI7QUFDckI7QUFDQTs7RUFFRSw4QkFBOEI7QUFDaEM7QUFDQTtFQUNFLFdBQVc7RUFDWCxZQUFZO0VBQ1osY0FBYztBQUNoQjtBQUNBO0VBQ0UsVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsU0FBUztFQUNULFNBQVM7RUFDVCxVQUFVO0FBQ1o7QUFDQTtFQUNFLGFBQWE7RUFDYixpQkFBaUI7RUFDakIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxNQUFNO0VBQ04sVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsVUFBVTtFQUNWLFlBQVk7QUFDZDtBQUNBO0VBQ0UsaUJBQWlCO0FBQ25CO0FBQ0E7O0VBRUUseUJBQXlCO0VBQ3pCLHdCQUF3QjtFQUN4Qix5QkFBeUI7RUFDekIsNEJBQTRCO0FBQzlCO0FBQ0E7RUFDRSx5QkFBeUI7RUFDekIsd0JBQXdCO0VBQ3hCLHlCQUF5QjtFQUN6Qiw0QkFBNEI7QUFDOUI7QUFDQTs7RUFFRSx5Q0FBeUM7RUFDekMsNkJBQTZCO0FBQy9CO0FBQ0E7RUFDRSwwQ0FBMEM7RUFDMUMsNkJBQTZCO0FBQy9CO0FBQ0E7O0VBRUUsc0JBQXNCO0VBQ3RCLHlEQUF5RDtBQUMzRDtBQUNBO0VBQ0UsaUVBQWlFO0FBQ25FO0FBQ0E7RUFDRTtJQUNFLHNCQUFzQjtJQUN0QiwwQkFBMEI7SUFDMUIsVUFBVTtFQUNaO0VBQ0E7SUFDRSxzQkFBc0I7SUFDdEIsMEJBQTBCO0VBQzVCO0FBQ0Y7QUFDQTtFQUNFO0lBQ0Usc0JBQXNCO0lBQ3RCLDBCQUEwQjtFQUM1QjtFQUNBO0lBQ0Usc0JBQXNCO0lBQ3RCLDBCQUEwQjtJQUMxQixVQUFVO0VBQ1o7QUFDRjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFlBQVk7RUFDWixhQUFhO0VBQ2IsbUJBQW1CO0VBQ25CLHNCQUFzQjtFQUN0Qiw2Q0FBNkM7QUFDL0M7QUFDQTtFQUNFLHNCQUFzQjtFQUN0Qiw2Q0FBNkM7QUFDL0M7QUFDQTtFQUNFLGFBQWE7QUFDZjtBQUNBO0VBQ0Usb0JBQW9CO0FBQ3RCO0FBQ0E7RUFDRSxlQUFlO0VBQ2YsWUFBWTtFQUNaLGdCQUFnQjtFQUNoQixXQUFXO0VBQ1gsZUFBZTtFQUNmLGNBQWM7RUFDZCxrQkFBa0I7RUFDbEIscUJBQXFCO0VBQ3JCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsMkJBQTJCO0FBQzdCO0FBQ0E7RUFDRSxrQkFBa0I7RUFDbEIsUUFBUTtFQUNSLFNBQVM7RUFDVCx5QkFBeUI7RUFDekIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxXQUFXO0VBQ1gsU0FBUztFQUNULGlCQUFpQjtFQUNqQix1QkFBdUI7RUFDdkIseUJBQXlCO0FBQzNCXCIsXCJzb3VyY2VzQ29udGVudFwiOltcIi5yYy1zbGlkZXIge1xcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDE0cHg7XFxuICBwYWRkaW5nOiA1cHggMDtcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG4gIHRvdWNoLWFjdGlvbjogbm9uZTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICAtd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMCk7XFxufVxcbi5yYy1zbGlkZXIgKiB7XFxuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiByZ2JhKDAsIDAsIDAsIDApO1xcbn1cXG4ucmMtc2xpZGVyLXJhaWwge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDEwMCU7XFxuICBoZWlnaHQ6IDRweDtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNlOWU5ZTk7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxufVxcbi5yYy1zbGlkZXItdHJhY2sge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgaGVpZ2h0OiA0cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjYWJlMmZiO1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZSB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMTRweDtcXG4gIGhlaWdodDogMTRweDtcXG4gIG1hcmdpbi10b3A6IC01cHg7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xcbiAgYm9yZGVyOiBzb2xpZCAycHggIzk2ZGJmYTtcXG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcXG4gIGN1cnNvcjogcG9pbnRlcjtcXG4gIGN1cnNvcjogLXdlYmtpdC1ncmFiO1xcbiAgY3Vyc29yOiBncmFiO1xcbiAgb3BhY2l0eTogMC44O1xcbiAgdG91Y2gtYWN0aW9uOiBwYW4teDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUtZHJhZ2dpbmcucmMtc2xpZGVyLWhhbmRsZS1kcmFnZ2luZy5yYy1zbGlkZXItaGFuZGxlLWRyYWdnaW5nIHtcXG4gIGJvcmRlci1jb2xvcjogIzU3YzVmNztcXG4gIGJveC1zaGFkb3c6IDAgMCAwIDVweCAjOTZkYmZhO1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZTpmb2N1cyB7XFxuICBvdXRsaW5lOiBub25lO1xcbiAgYm94LXNoYWRvdzogbm9uZTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6Zm9jdXMtdmlzaWJsZSB7XFxuICBib3JkZXItY29sb3I6ICMyZGI3ZjU7XFxuICBib3gtc2hhZG93OiAwIDAgMCAzcHggIzk2ZGJmYTtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGUtY2xpY2stZm9jdXNlZDpmb2N1cyB7XFxuICBib3JkZXItY29sb3I6ICM5NmRiZmE7XFxuICBib3gtc2hhZG93OiB1bnNldDtcXG59XFxuLnJjLXNsaWRlci1oYW5kbGU6aG92ZXIge1xcbiAgYm9yZGVyLWNvbG9yOiAjNTdjNWY3O1xcbn1cXG4ucmMtc2xpZGVyLWhhbmRsZTphY3RpdmUge1xcbiAgYm9yZGVyLWNvbG9yOiAjNTdjNWY3O1xcbiAgYm94LXNoYWRvdzogMCAwIDVweCAjNTdjNWY3O1xcbiAgY3Vyc29yOiAtd2Via2l0LWdyYWJiaW5nO1xcbiAgY3Vyc29yOiBncmFiYmluZztcXG59XFxuLnJjLXNsaWRlci1tYXJrIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogMThweDtcXG4gIGxlZnQ6IDA7XFxuICB3aWR0aDogMTAwJTtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG59XFxuLnJjLXNsaWRlci1tYXJrLXRleHQge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xcbiAgY29sb3I6ICM5OTk7XFxuICB0ZXh0LWFsaWduOiBjZW50ZXI7XFxuICB2ZXJ0aWNhbC1hbGlnbjogbWlkZGxlO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ucmMtc2xpZGVyLW1hcmstdGV4dC1hY3RpdmUge1xcbiAgY29sb3I6ICM2NjY7XFxufVxcbi5yYy1zbGlkZXItc3RlcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMTAwJTtcXG4gIGhlaWdodDogNHB4O1xcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XFxuICBwb2ludGVyLWV2ZW50czogbm9uZTtcXG59XFxuLnJjLXNsaWRlci1kb3Qge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgYm90dG9tOiAtMnB4O1xcbiAgd2lkdGg6IDhweDtcXG4gIGhlaWdodDogOHB4O1xcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXI6IDJweCBzb2xpZCAjZTllOWU5O1xcbiAgYm9yZGVyLXJhZGl1czogNTAlO1xcbiAgY3Vyc29yOiBwb2ludGVyO1xcbn1cXG4ucmMtc2xpZGVyLWRvdC1hY3RpdmUge1xcbiAgYm9yZGVyLWNvbG9yOiAjOTZkYmZhO1xcbn1cXG4ucmMtc2xpZGVyLWRvdC1yZXZlcnNlIHtcXG4gIG1hcmdpbi1yaWdodDogLTRweDtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCB7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZTllOWU5O1xcbn1cXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItdHJhY2sge1xcbiAgYmFja2dyb3VuZC1jb2xvcjogI2NjYztcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLWhhbmRsZSxcXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItZG90IHtcXG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmY7XFxuICBib3JkZXItY29sb3I6ICNjY2M7XFxuICBib3gtc2hhZG93OiBub25lO1xcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcXG59XFxuLnJjLXNsaWRlci1kaXNhYmxlZCAucmMtc2xpZGVyLW1hcmstdGV4dCxcXG4ucmMtc2xpZGVyLWRpc2FibGVkIC5yYy1zbGlkZXItZG90IHtcXG4gIGN1cnNvcjogbm90LWFsbG93ZWQgIWltcG9ydGFudDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCB7XFxuICB3aWR0aDogMTRweDtcXG4gIGhlaWdodDogMTAwJTtcXG4gIHBhZGRpbmc6IDAgNXB4O1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItcmFpbCB7XFxuICB3aWR0aDogNHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItdHJhY2sge1xcbiAgYm90dG9tOiAwO1xcbiAgbGVmdDogNXB4O1xcbiAgd2lkdGg6IDRweDtcXG59XFxuLnJjLXNsaWRlci12ZXJ0aWNhbCAucmMtc2xpZGVyLWhhbmRsZSB7XFxuICBtYXJnaW4tdG9wOiAwO1xcbiAgbWFyZ2luLWxlZnQ6IC01cHg7XFxuICB0b3VjaC1hY3Rpb246IHBhbi15O1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItbWFyayB7XFxuICB0b3A6IDA7XFxuICBsZWZ0OiAxOHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItc3RlcCB7XFxuICB3aWR0aDogNHB4O1xcbiAgaGVpZ2h0OiAxMDAlO1xcbn1cXG4ucmMtc2xpZGVyLXZlcnRpY2FsIC5yYy1zbGlkZXItZG90IHtcXG4gIG1hcmdpbi1sZWZ0OiAtMnB4O1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLFxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyIHtcXG4gIGRpc3BsYXk6IGJsb2NrICFpbXBvcnRhbnQ7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHBhdXNlZDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZSB7XFxuICBkaXNwbGF5OiBibG9jayAhaW1wb3J0YW50O1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAwLjNzO1xcbiAgYW5pbWF0aW9uLWZpbGwtbW9kZTogYm90aDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tZW50ZXIucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWVudGVyLWFjdGl2ZSxcXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWFwcGVhci5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tYXBwZWFyLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNTbGlkZXJUb29sdGlwWm9vbURvd25JbjtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtem9vbS1kb3duLWxlYXZlLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZS1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjU2xpZGVyVG9vbHRpcFpvb21Eb3duT3V0O1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHJ1bm5pbmc7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC16b29tLWRvd24tZW50ZXIsXFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1hcHBlYXIge1xcbiAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gIGFuaW1hdGlvbi10aW1pbmctZnVuY3Rpb246IGN1YmljLWJlemllcigwLjIzLCAxLCAwLjMyLCAxKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLXpvb20tZG93bi1sZWF2ZSB7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC43NTUsIDAuMDUsIDAuODU1LCAwLjA2KTtcXG59XFxuQGtleWZyYW1lcyByY1NsaWRlclRvb2x0aXBab29tRG93bkluIHtcXG4gIDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICAgIG9wYWNpdHk6IDA7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDEwMCU7XFxuICB9XFxufVxcbkBrZXlmcmFtZXMgcmNTbGlkZXJUb29sdGlwWm9vbURvd25PdXQge1xcbiAgMCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDEsIDEpO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgMTAwJTtcXG4gIH1cXG4gIDEwMCUge1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgMTAwJTtcXG4gICAgb3BhY2l0eTogMDtcXG4gIH1cXG59XFxuLnJjLXNsaWRlci10b29sdGlwIHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHRvcDogLTk5OTlweDtcXG4gIGxlZnQ6IC05OTk5cHg7XFxuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwICoge1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwKTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWhpZGRlbiB7XFxuICBkaXNwbGF5OiBub25lO1xcbn1cXG4ucmMtc2xpZGVyLXRvb2x0aXAtcGxhY2VtZW50LXRvcCB7XFxuICBwYWRkaW5nOiA0cHggMCA4cHggMDtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWlubmVyIHtcXG4gIG1pbi13aWR0aDogMjRweDtcXG4gIGhlaWdodDogMjRweDtcXG4gIHBhZGRpbmc6IDZweCAycHg7XFxuICBjb2xvcjogI2ZmZjtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG4gIGxpbmUtaGVpZ2h0OiAxO1xcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcbiAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogIzZjNmM2YztcXG4gIGJvcmRlci1yYWRpdXM6IDZweDtcXG4gIGJveC1zaGFkb3c6IDAgMCA0cHggI2Q5ZDlkOTtcXG59XFxuLnJjLXNsaWRlci10b29sdGlwLWFycm93IHtcXG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcXG4gIHdpZHRoOiAwO1xcbiAgaGVpZ2h0OiAwO1xcbiAgYm9yZGVyLWNvbG9yOiB0cmFuc3BhcmVudDtcXG4gIGJvcmRlci1zdHlsZTogc29saWQ7XFxufVxcbi5yYy1zbGlkZXItdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy1zbGlkZXItdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDRweDtcXG4gIGxlZnQ6IDUwJTtcXG4gIG1hcmdpbi1sZWZ0OiAtNHB4O1xcbiAgYm9yZGVyLXdpZHRoOiA0cHggNHB4IDA7XFxuICBib3JkZXItdG9wLWNvbG9yOiAjNmM2YzZjO1xcbn1cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///687\n')},467:(module,__webpack_exports__,__webpack_require__)=>{"use strict";eval('/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(537);\n/* harmony import */ var _css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(645);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, ".rc-tooltip.rc-tooltip-zoom-appear,\\n.rc-tooltip.rc-tooltip-zoom-enter {\\n opacity: 0;\\n}\\n.rc-tooltip.rc-tooltip-zoom-enter,\\n.rc-tooltip.rc-tooltip-zoom-leave {\\n display: block;\\n}\\n.rc-tooltip-zoom-enter,\\n.rc-tooltip-zoom-appear {\\n opacity: 0;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-leave {\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,\\n.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {\\n animation-name: rcToolTipZoomIn;\\n animation-play-state: running;\\n}\\n.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {\\n animation-name: rcToolTipZoomOut;\\n animation-play-state: running;\\n}\\n@keyframes rcToolTipZoomIn {\\n 0% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n 100% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n}\\n@keyframes rcToolTipZoomOut {\\n 0% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n 100% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n}\\n.rc-tooltip {\\n position: absolute;\\n z-index: 1070;\\n display: block;\\n visibility: visible;\\n font-size: 12px;\\n line-height: 1.5;\\n opacity: 0.9;\\n}\\n.rc-tooltip-hidden {\\n display: none;\\n}\\n.rc-tooltip-placement-top,\\n.rc-tooltip-placement-topLeft,\\n.rc-tooltip-placement-topRight {\\n padding: 5px 0 9px 0;\\n}\\n.rc-tooltip-placement-right,\\n.rc-tooltip-placement-rightTop,\\n.rc-tooltip-placement-rightBottom {\\n padding: 0 5px 0 9px;\\n}\\n.rc-tooltip-placement-bottom,\\n.rc-tooltip-placement-bottomLeft,\\n.rc-tooltip-placement-bottomRight {\\n padding: 9px 0 5px 0;\\n}\\n.rc-tooltip-placement-left,\\n.rc-tooltip-placement-leftTop,\\n.rc-tooltip-placement-leftBottom {\\n padding: 0 9px 0 5px;\\n}\\n.rc-tooltip-inner {\\n padding: 8px 10px;\\n color: #fff;\\n text-align: left;\\n text-decoration: none;\\n background-color: #373737;\\n border-radius: 6px;\\n box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);\\n min-height: 34px;\\n}\\n.rc-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow,\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n bottom: 4px;\\n margin-left: -5px;\\n border-width: 5px 5px 0;\\n border-top-color: #373737;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n left: 4px;\\n margin-top: -5px;\\n border-width: 5px 5px 5px 0;\\n border-right-color: #373737;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n right: 4px;\\n margin-top: -5px;\\n border-width: 5px 0 5px 5px;\\n border-left-color: #373737;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n top: 4px;\\n margin-left: -5px;\\n border-width: 0 5px 5px;\\n border-bottom-color: #373737;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n", "",{"version":3,"sources":["webpack://./node_modules/rc-tooltip/assets/bootstrap.css"],"names":[],"mappings":"AAAA;;EAEE,UAAU;AACZ;AACA;;EAEE,cAAc;AAChB;AACA;;EAEE,UAAU;EACV,wBAAwB;EACxB,yBAAyB;EACzB,+DAA+D;EAC/D,4BAA4B;AAC9B;AACA;EACE,wBAAwB;EACxB,yBAAyB;EACzB,8DAA8D;EAC9D,4BAA4B;AAC9B;AACA;;EAEE,+BAA+B;EAC/B,6BAA6B;AAC/B;AACA;EACE,gCAAgC;EAChC,6BAA6B;AAC/B;AACA;EACE;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;EACA;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;AACF;AACA;EACE;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;EACA;IACE,UAAU;IACV,yBAAyB;IACzB,sBAAsB;EACxB;AACF;AACA;EACE,kBAAkB;EAClB,aAAa;EACb,cAAc;EACd,mBAAmB;EACnB,eAAe;EACf,gBAAgB;EAChB,YAAY;AACd;AACA;EACE,aAAa;AACf;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;;;EAGE,oBAAoB;AACtB;AACA;EACE,iBAAiB;EACjB,WAAW;EACX,gBAAgB;EAChB,qBAAqB;EACrB,yBAAyB;EACzB,kBAAkB;EAClB,uCAAuC;EACvC,gBAAgB;AAClB;AACA;EACE,kBAAkB;EAClB,QAAQ;EACR,SAAS;EACT,yBAAyB;EACzB,mBAAmB;AACrB;AACA;;;EAGE,WAAW;EACX,iBAAiB;EACjB,uBAAuB;EACvB,yBAAyB;AAC3B;AACA;EACE,SAAS;AACX;AACA;EACE,SAAS;AACX;AACA;EACE,UAAU;AACZ;AACA;;;EAGE,SAAS;EACT,gBAAgB;EAChB,2BAA2B;EAC3B,2BAA2B;AAC7B;AACA;EACE,QAAQ;AACV;AACA;EACE,QAAQ;EACR,aAAa;AACf;AACA;EACE,WAAW;AACb;AACA;;;EAGE,UAAU;EACV,gBAAgB;EAChB,2BAA2B;EAC3B,0BAA0B;AAC5B;AACA;EACE,QAAQ;AACV;AACA;EACE,QAAQ;EACR,aAAa;AACf;AACA;EACE,WAAW;AACb;AACA;;;EAGE,QAAQ;EACR,iBAAiB;EACjB,uBAAuB;EACvB,4BAA4B;AAC9B;AACA;EACE,SAAS;AACX;AACA;EACE,SAAS;AACX;AACA;EACE,UAAU;AACZ","sourcesContent":[".rc-tooltip.rc-tooltip-zoom-appear,\\n.rc-tooltip.rc-tooltip-zoom-enter {\\n opacity: 0;\\n}\\n.rc-tooltip.rc-tooltip-zoom-enter,\\n.rc-tooltip.rc-tooltip-zoom-leave {\\n display: block;\\n}\\n.rc-tooltip-zoom-enter,\\n.rc-tooltip-zoom-appear {\\n opacity: 0;\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-leave {\\n animation-duration: 0.3s;\\n animation-fill-mode: both;\\n animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);\\n animation-play-state: paused;\\n}\\n.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,\\n.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {\\n animation-name: rcToolTipZoomIn;\\n animation-play-state: running;\\n}\\n.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {\\n animation-name: rcToolTipZoomOut;\\n animation-play-state: running;\\n}\\n@keyframes rcToolTipZoomIn {\\n 0% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n 100% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n}\\n@keyframes rcToolTipZoomOut {\\n 0% {\\n opacity: 1;\\n transform-origin: 50% 50%;\\n transform: scale(1, 1);\\n }\\n 100% {\\n opacity: 0;\\n transform-origin: 50% 50%;\\n transform: scale(0, 0);\\n }\\n}\\n.rc-tooltip {\\n position: absolute;\\n z-index: 1070;\\n display: block;\\n visibility: visible;\\n font-size: 12px;\\n line-height: 1.5;\\n opacity: 0.9;\\n}\\n.rc-tooltip-hidden {\\n display: none;\\n}\\n.rc-tooltip-placement-top,\\n.rc-tooltip-placement-topLeft,\\n.rc-tooltip-placement-topRight {\\n padding: 5px 0 9px 0;\\n}\\n.rc-tooltip-placement-right,\\n.rc-tooltip-placement-rightTop,\\n.rc-tooltip-placement-rightBottom {\\n padding: 0 5px 0 9px;\\n}\\n.rc-tooltip-placement-bottom,\\n.rc-tooltip-placement-bottomLeft,\\n.rc-tooltip-placement-bottomRight {\\n padding: 9px 0 5px 0;\\n}\\n.rc-tooltip-placement-left,\\n.rc-tooltip-placement-leftTop,\\n.rc-tooltip-placement-leftBottom {\\n padding: 0 9px 0 5px;\\n}\\n.rc-tooltip-inner {\\n padding: 8px 10px;\\n color: #fff;\\n text-align: left;\\n text-decoration: none;\\n background-color: #373737;\\n border-radius: 6px;\\n box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);\\n min-height: 34px;\\n}\\n.rc-tooltip-arrow {\\n position: absolute;\\n width: 0;\\n height: 0;\\n border-color: transparent;\\n border-style: solid;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow,\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n bottom: 4px;\\n margin-left: -5px;\\n border-width: 5px 5px 0;\\n border-top-color: #373737;\\n}\\n.rc-tooltip-placement-top .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-topLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-topRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n left: 4px;\\n margin-top: -5px;\\n border-width: 5px 5px 5px 0;\\n border-right-color: #373737;\\n}\\n.rc-tooltip-placement-right .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-rightTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow,\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n right: 4px;\\n margin-top: -5px;\\n border-width: 5px 0 5px 5px;\\n border-left-color: #373737;\\n}\\n.rc-tooltip-placement-left .rc-tooltip-arrow {\\n top: 50%;\\n}\\n.rc-tooltip-placement-leftTop .rc-tooltip-arrow {\\n top: 15%;\\n margin-top: 0;\\n}\\n.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {\\n bottom: 15%;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n top: 4px;\\n margin-left: -5px;\\n border-width: 0 5px 5px;\\n border-bottom-color: #373737;\\n}\\n.rc-tooltip-placement-bottom .rc-tooltip-arrow {\\n left: 50%;\\n}\\n.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {\\n left: 15%;\\n}\\n.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {\\n right: 15%;\\n}\\n"],"sourceRoot":""}]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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c0QsZ0JBQWdCLEdBQUcsNkpBQTZKLGFBQWEsc0JBQXNCLDRCQUE0QixpQ0FBaUMsR0FBRyxrREFBa0QsY0FBYyxHQUFHLHNEQUFzRCxjQUFjLEdBQUcsdURBQXVELGVBQWUsR0FBRyxxQkFBcUI7QUFDeDRUO0FBQ0EsaUVBQWUsdUJBQXVCLEVBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdG9vbHRpcC9hc3NldHMvYm9vdHN0cmFwLmNzcz81OTY0Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIEltcG9ydHNcbmltcG9ydCBfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fIGZyb20gXCIuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi8uLi9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9hcGkuanNcIjtcbnZhciBfX19DU1NfTE9BREVSX0VYUE9SVF9fXyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhfX19DU1NfTE9BREVSX0FQSV9TT1VSQ0VNQVBfSU1QT1JUX19fKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBcIi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIsXFxuLnJjLXRvb2x0aXAucmMtdG9vbHRpcC16b29tLWVudGVyIHtcXG4gIG9wYWNpdHk6IDA7XFxufVxcbi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1lbnRlcixcXG4ucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tbGVhdmUge1xcbiAgZGlzcGxheTogYmxvY2s7XFxufVxcbi5yYy10b29sdGlwLXpvb20tZW50ZXIsXFxuLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIge1xcbiAgb3BhY2l0eTogMDtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC4xOCwgMC44OSwgMC4zMiwgMS4yOCk7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWxlYXZlIHtcXG4gIGFuaW1hdGlvbi1kdXJhdGlvbjogMC4zcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGJvdGg7XFxuICBhbmltYXRpb24tdGltaW5nLWZ1bmN0aW9uOiBjdWJpYy1iZXppZXIoMC42LCAtMC4zLCAwLjc0LCAwLjA1KTtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBwYXVzZWQ7XFxufVxcbi5yYy10b29sdGlwLXpvb20tZW50ZXIucmMtdG9vbHRpcC16b29tLWVudGVyLWFjdGl2ZSxcXG4ucmMtdG9vbHRpcC16b29tLWFwcGVhci5yYy10b29sdGlwLXpvb20tYXBwZWFyLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNUb29sVGlwWm9vbUluO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHJ1bm5pbmc7XFxufVxcbi5yYy10b29sdGlwLXpvb20tbGVhdmUucmMtdG9vbHRpcC16b29tLWxlYXZlLWFjdGl2ZSB7XFxuICBhbmltYXRpb24tbmFtZTogcmNUb29sVGlwWm9vbU91dDtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG5Aa2V5ZnJhbWVzIHJjVG9vbFRpcFpvb21JbiB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDA7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMCwgMCk7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gIH1cXG59XFxuQGtleWZyYW1lcyByY1Rvb2xUaXBab29tT3V0IHtcXG4gIDAlIHtcXG4gICAgb3BhY2l0eTogMTtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcXG4gIH1cXG4gIDEwMCUge1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlO1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgfVxcbn1cXG4ucmMtdG9vbHRpcCB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB6LWluZGV4OiAxMDcwO1xcbiAgZGlzcGxheTogYmxvY2s7XFxuICB2aXNpYmlsaXR5OiB2aXNpYmxlO1xcbiAgZm9udC1zaXplOiAxMnB4O1xcbiAgbGluZS1oZWlnaHQ6IDEuNTtcXG4gIG9wYWNpdHk6IDAuOTtcXG59XFxuLnJjLXRvb2x0aXAtaGlkZGVuIHtcXG4gIGRpc3BsYXk6IG5vbmU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3AsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcExlZnQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcFJpZ2h0IHtcXG4gIHBhZGRpbmc6IDVweCAwIDlweCAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0VG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodEJvdHRvbSB7XFxuICBwYWRkaW5nOiAwIDVweCAwIDlweDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tTGVmdCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQge1xcbiAgcGFkZGluZzogOXB4IDAgNXB4IDA7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0VG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIHtcXG4gIHBhZGRpbmc6IDAgOXB4IDAgNXB4O1xcbn1cXG4ucmMtdG9vbHRpcC1pbm5lciB7XFxuICBwYWRkaW5nOiA4cHggMTBweDtcXG4gIGNvbG9yOiAjZmZmO1xcbiAgdGV4dC1hbGlnbjogbGVmdDtcXG4gIHRleHQtZGVjb3JhdGlvbjogbm9uZTtcXG4gIGJhY2tncm91bmQtY29sb3I6ICMzNzM3Mzc7XFxuICBib3JkZXItcmFkaXVzOiA2cHg7XFxuICBib3gtc2hhZG93OiAwIDAgNHB4IHJnYmEoMCwgMCwgMCwgMC4xNyk7XFxuICBtaW4taGVpZ2h0OiAzNHB4O1xcbn1cXG4ucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBwb3NpdGlvbjogYWJzb2x1dGU7XFxuICB3aWR0aDogMDtcXG4gIGhlaWdodDogMDtcXG4gIGJvcmRlci1jb2xvcjogdHJhbnNwYXJlbnQ7XFxuICBib3JkZXItc3R5bGU6IHNvbGlkO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BSaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDRweDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiA1cHggNXB4IDA7XFxuICBib3JkZXItdG9wLWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcExlZnQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcmlnaHQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodFRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20gLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogNHB4O1xcbiAgbWFyZ2luLXRvcDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDVweCA1cHggMDtcXG4gIGJvcmRlci1yaWdodC1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogNTAlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRUb3AgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiAxNSU7XFxuICBtYXJnaW4tdG9wOiAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20gLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiAxNSU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0VG9wIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiA0cHg7XFxuICBtYXJnaW4tdG9wOiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiA1cHggMCA1cHggNXB4O1xcbiAgYm9yZGVyLWxlZnQtY29sb3I6ICMzNzM3Mzc7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogNTAlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDE1JTtcXG4gIG1hcmdpbi10b3A6IDA7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1sZWZ0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGJvdHRvbTogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tIC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21MZWZ0IC5yYy10b29sdGlwLWFycm93LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21SaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDRweDtcXG4gIG1hcmdpbi1sZWZ0OiAtNXB4O1xcbiAgYm9yZGVyLXdpZHRoOiAwIDVweCA1cHg7XFxuICBib3JkZXItYm90dG9tLWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbUxlZnQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgbGVmdDogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcmlnaHQ6IDE1JTtcXG59XFxuXCIsIFwiXCIse1widmVyc2lvblwiOjMsXCJzb3VyY2VzXCI6W1wid2VicGFjazovLy4vbm9kZV9tb2R1bGVzL3JjLXRvb2x0aXAvYXNzZXRzL2Jvb3RzdHJhcC5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUE7O0VBRUUsVUFBVTtBQUNaO0FBQ0E7O0VBRUUsY0FBYztBQUNoQjtBQUNBOztFQUVFLFVBQVU7RUFDVix3QkFBd0I7RUFDeEIseUJBQXlCO0VBQ3pCLCtEQUErRDtFQUMvRCw0QkFBNEI7QUFDOUI7QUFDQTtFQUNFLHdCQUF3QjtFQUN4Qix5QkFBeUI7RUFDekIsOERBQThEO0VBQzlELDRCQUE0QjtBQUM5QjtBQUNBOztFQUVFLCtCQUErQjtFQUMvQiw2QkFBNkI7QUFDL0I7QUFDQTtFQUNFLGdDQUFnQztFQUNoQyw2QkFBNkI7QUFDL0I7QUFDQTtFQUNFO0lBQ0UsVUFBVTtJQUNWLHlCQUF5QjtJQUN6QixzQkFBc0I7RUFDeEI7RUFDQTtJQUNFLFVBQVU7SUFDVix5QkFBeUI7SUFDekIsc0JBQXNCO0VBQ3hCO0FBQ0Y7QUFDQTtFQUNFO0lBQ0UsVUFBVTtJQUNWLHlCQUF5QjtJQUN6QixzQkFBc0I7RUFDeEI7RUFDQTtJQUNFLFVBQVU7SUFDVix5QkFBeUI7SUFDekIsc0JBQXNCO0VBQ3hCO0FBQ0Y7QUFDQTtFQUNFLGtCQUFrQjtFQUNsQixhQUFhO0VBQ2IsY0FBYztFQUNkLG1CQUFtQjtFQUNuQixlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLFlBQVk7QUFDZDtBQUNBO0VBQ0UsYUFBYTtBQUNmO0FBQ0E7OztFQUdFLG9CQUFvQjtBQUN0QjtBQUNBOzs7RUFHRSxvQkFBb0I7QUFDdEI7QUFDQTs7O0VBR0Usb0JBQW9CO0FBQ3RCO0FBQ0E7OztFQUdFLG9CQUFvQjtBQUN0QjtBQUNBO0VBQ0UsaUJBQWlCO0VBQ2pCLFdBQVc7RUFDWCxnQkFBZ0I7RUFDaEIscUJBQXFCO0VBQ3JCLHlCQUF5QjtFQUN6QixrQkFBa0I7RUFDbEIsdUNBQXVDO0VBQ3ZDLGdCQUFnQjtBQUNsQjtBQUNBO0VBQ0Usa0JBQWtCO0VBQ2xCLFFBQVE7RUFDUixTQUFTO0VBQ1QseUJBQXlCO0VBQ3pCLG1CQUFtQjtBQUNyQjtBQUNBOzs7RUFHRSxXQUFXO0VBQ1gsaUJBQWlCO0VBQ2pCLHVCQUF1QjtFQUN2Qix5QkFBeUI7QUFDM0I7QUFDQTtFQUNFLFNBQVM7QUFDWDtBQUNBO0VBQ0UsU0FBUztBQUNYO0FBQ0E7RUFDRSxVQUFVO0FBQ1o7QUFDQTs7O0VBR0UsU0FBUztFQUNULGdCQUFnQjtFQUNoQiwyQkFBMkI7RUFDM0IsMkJBQTJCO0FBQzdCO0FBQ0E7RUFDRSxRQUFRO0FBQ1Y7QUFDQTtFQUNFLFFBQVE7RUFDUixhQUFhO0FBQ2Y7QUFDQTtFQUNFLFdBQVc7QUFDYjtBQUNBOzs7RUFHRSxVQUFVO0VBQ1YsZ0JBQWdCO0VBQ2hCLDJCQUEyQjtFQUMzQiwwQkFBMEI7QUFDNUI7QUFDQTtFQUNFLFFBQVE7QUFDVjtBQUNBO0VBQ0UsUUFBUTtFQUNSLGFBQWE7QUFDZjtBQUNBO0VBQ0UsV0FBVztBQUNiO0FBQ0E7OztFQUdFLFFBQVE7RUFDUixpQkFBaUI7RUFDakIsdUJBQXVCO0VBQ3ZCLDRCQUE0QjtBQUM5QjtBQUNBO0VBQ0UsU0FBUztBQUNYO0FBQ0E7RUFDRSxTQUFTO0FBQ1g7QUFDQTtFQUNFLFVBQVU7QUFDWlwiLFwic291cmNlc0NvbnRlbnRcIjpbXCIucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tYXBwZWFyLFxcbi5yYy10b29sdGlwLnJjLXRvb2x0aXAtem9vbS1lbnRlciB7XFxuICBvcGFjaXR5OiAwO1xcbn1cXG4ucmMtdG9vbHRpcC5yYy10b29sdGlwLXpvb20tZW50ZXIsXFxuLnJjLXRvb2x0aXAucmMtdG9vbHRpcC16b29tLWxlYXZlIHtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWVudGVyLFxcbi5yYy10b29sdGlwLXpvb20tYXBwZWFyIHtcXG4gIG9wYWNpdHk6IDA7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuMTgsIDAuODksIDAuMzIsIDEuMjgpO1xcbiAgYW5pbWF0aW9uLXBsYXktc3RhdGU6IHBhdXNlZDtcXG59XFxuLnJjLXRvb2x0aXAtem9vbS1sZWF2ZSB7XFxuICBhbmltYXRpb24tZHVyYXRpb246IDAuM3M7XFxuICBhbmltYXRpb24tZmlsbC1tb2RlOiBib3RoO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogY3ViaWMtYmV6aWVyKDAuNiwgLTAuMywgMC43NCwgMC4wNSk7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcGF1c2VkO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWVudGVyLnJjLXRvb2x0aXAtem9vbS1lbnRlci1hY3RpdmUsXFxuLnJjLXRvb2x0aXAtem9vbS1hcHBlYXIucmMtdG9vbHRpcC16b29tLWFwcGVhci1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjVG9vbFRpcFpvb21JbjtcXG4gIGFuaW1hdGlvbi1wbGF5LXN0YXRlOiBydW5uaW5nO1xcbn1cXG4ucmMtdG9vbHRpcC16b29tLWxlYXZlLnJjLXRvb2x0aXAtem9vbS1sZWF2ZS1hY3RpdmUge1xcbiAgYW5pbWF0aW9uLW5hbWU6IHJjVG9vbFRpcFpvb21PdXQ7XFxuICBhbmltYXRpb24tcGxheS1zdGF0ZTogcnVubmluZztcXG59XFxuQGtleWZyYW1lcyByY1Rvb2xUaXBab29tSW4ge1xcbiAgMCUge1xcbiAgICBvcGFjaXR5OiAwO1xcbiAgICB0cmFuc2Zvcm0tb3JpZ2luOiA1MCUgNTAlO1xcbiAgICB0cmFuc2Zvcm06IHNjYWxlKDAsIDApO1xcbiAgfVxcbiAgMTAwJSB7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICB9XFxufVxcbkBrZXlmcmFtZXMgcmNUb29sVGlwWm9vbU91dCB7XFxuICAwJSB7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHRyYW5zZm9ybS1vcmlnaW46IDUwJSA1MCU7XFxuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XFxuICB9XFxuICAxMDAlIHtcXG4gICAgb3BhY2l0eTogMDtcXG4gICAgdHJhbnNmb3JtLW9yaWdpbjogNTAlIDUwJTtcXG4gICAgdHJhbnNmb3JtOiBzY2FsZSgwLCAwKTtcXG4gIH1cXG59XFxuLnJjLXRvb2x0aXAge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgei1pbmRleDogMTA3MDtcXG4gIGRpc3BsYXk6IGJsb2NrO1xcbiAgdmlzaWJpbGl0eTogdmlzaWJsZTtcXG4gIGZvbnQtc2l6ZTogMTJweDtcXG4gIGxpbmUtaGVpZ2h0OiAxLjU7XFxuICBvcGFjaXR5OiAwLjk7XFxufVxcbi5yYy10b29sdGlwLWhpZGRlbiB7XFxuICBkaXNwbGF5OiBub25lO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wLFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BSaWdodCB7XFxuICBwYWRkaW5nOiA1cHggMCA5cHggMDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0LFxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodFRvcCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRCb3R0b20ge1xcbiAgcGFkZGluZzogMCA1cHggMCA5cHg7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b20sXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbUxlZnQsXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbVJpZ2h0IHtcXG4gIHBhZGRpbmc6IDlweCAwIDVweCAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSB7XFxuICBwYWRkaW5nOiAwIDlweCAwIDVweDtcXG59XFxuLnJjLXRvb2x0aXAtaW5uZXIge1xcbiAgcGFkZGluZzogOHB4IDEwcHg7XFxuICBjb2xvcjogI2ZmZjtcXG4gIHRleHQtYWxpZ246IGxlZnQ7XFxuICB0ZXh0LWRlY29yYXRpb246IG5vbmU7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMzczNzM3O1xcbiAgYm9yZGVyLXJhZGl1czogNnB4O1xcbiAgYm94LXNoYWRvdzogMCAwIDRweCByZ2JhKDAsIDAsIDAsIDAuMTcpO1xcbiAgbWluLWhlaWdodDogMzRweDtcXG59XFxuLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgcG9zaXRpb246IGFic29sdXRlO1xcbiAgd2lkdGg6IDA7XFxuICBoZWlnaHQ6IDA7XFxuICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50O1xcbiAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wTGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtdG9wUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgYm90dG9tOiA0cHg7XFxuICBtYXJnaW4tbGVmdDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDVweCAwO1xcbiAgYm9yZGVyLXRvcC1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBsZWZ0OiA1MCU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC10b3BMZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXRvcFJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiAxNSU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtcmlnaHRUb3AgLnJjLXRvb2x0aXAtYXJyb3csXFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDRweDtcXG4gIG1hcmdpbi10b3A6IC01cHg7XFxuICBib3JkZXItd2lkdGg6IDVweCA1cHggNXB4IDA7XFxuICBib3JkZXItcmlnaHQtY29sb3I6ICMzNzM3Mzc7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1yaWdodCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0VG9wIC5yYy10b29sdGlwLWFycm93IHtcXG4gIHRvcDogMTUlO1xcbiAgbWFyZ2luLXRvcDogMDtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LXJpZ2h0Qm90dG9tIC5yYy10b29sdGlwLWFycm93IHtcXG4gIGJvdHRvbTogMTUlO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdFRvcCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICByaWdodDogNHB4O1xcbiAgbWFyZ2luLXRvcDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogNXB4IDAgNXB4IDVweDtcXG4gIGJvcmRlci1sZWZ0LWNvbG9yOiAjMzczNzM3O1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdCAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICB0b3A6IDUwJTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWxlZnRUb3AgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiAxNSU7XFxuICBtYXJnaW4tdG9wOiAwO1xcbn1cXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtbGVmdEJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBib3R0b206IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tTGVmdCAucmMtdG9vbHRpcC1hcnJvdyxcXG4ucmMtdG9vbHRpcC1wbGFjZW1lbnQtYm90dG9tUmlnaHQgLnJjLXRvb2x0aXAtYXJyb3cge1xcbiAgdG9wOiA0cHg7XFxuICBtYXJnaW4tbGVmdDogLTVweDtcXG4gIGJvcmRlci13aWR0aDogMCA1cHggNXB4O1xcbiAgYm9yZGVyLWJvdHRvbS1jb2xvcjogIzM3MzczNztcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbSAucmMtdG9vbHRpcC1hcnJvdyB7XFxuICBsZWZ0OiA1MCU7XFxufVxcbi5yYy10b29sdGlwLXBsYWNlbWVudC1ib3R0b21MZWZ0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIGxlZnQ6IDE1JTtcXG59XFxuLnJjLXRvb2x0aXAtcGxhY2VtZW50LWJvdHRvbVJpZ2h0IC5yYy10b29sdGlwLWFycm93IHtcXG4gIHJpZ2h0OiAxNSU7XFxufVxcblwiXSxcInNvdXJjZVJvb3RcIjpcIlwifV0pO1xuLy8gRXhwb3J0c1xuZXhwb3J0IGRlZmF1bHQgX19fQ1NTX0xPQURFUl9FWFBPUlRfX187XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///467\n')},645:module=>{"use strict";eval('\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = "";\n var needLayer = typeof item[5] !== "undefined";\n if (item[4]) {\n content += "@supports (".concat(item[4], ") {");\n }\n if (item[2]) {\n content += "@media ".concat(item[2], " {");\n }\n if (needLayer) {\n content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += "}";\n }\n if (item[2]) {\n content += "}";\n }\n if (item[4]) {\n content += "}";\n }\n return content;\n }).join("");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === "string") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== "undefined") {\n if (typeof item[5] === "undefined") {\n item[5] = layer;\n } else {\n item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = "@media ".concat(item[2], " {").concat(item[1], "}");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = "".concat(supports);\n } else {\n item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjQ1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0EscUZBQXFGO0FBQ3JGO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixpQkFBaUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHFCQUFxQjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzRkFBc0YscUJBQXFCO0FBQzNHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixpREFBaUQscUJBQXFCO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVixzREFBc0QscUJBQXFCO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzPzI0ZmIiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qXG4gIE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4gIEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKSB7XG4gIHZhciBsaXN0ID0gW107XG5cbiAgLy8gcmV0dXJuIHRoZSBsaXN0IG9mIG1vZHVsZXMgYXMgY3NzIHN0cmluZ1xuICBsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICB2YXIgY29udGVudCA9IFwiXCI7XG4gICAgICB2YXIgbmVlZExheWVyID0gdHlwZW9mIGl0ZW1bNV0gIT09IFwidW5kZWZpbmVkXCI7XG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwiQHN1cHBvcnRzIChcIi5jb25jYXQoaXRlbVs0XSwgXCIpIHtcIik7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICBjb250ZW50ICs9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpO1xuICAgICAgfVxuICAgICAgaWYgKG5lZWRMYXllcikge1xuICAgICAgICBjb250ZW50ICs9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIik7XG4gICAgICB9XG4gICAgICBjb250ZW50ICs9IGNzc1dpdGhNYXBwaW5nVG9TdHJpbmcoaXRlbSk7XG4gICAgICBpZiAobmVlZExheWVyKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJ9XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuICAgICAgaWYgKGl0ZW1bNF0pIHtcbiAgICAgICAgY29udGVudCArPSBcIn1cIjtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb250ZW50O1xuICAgIH0pLmpvaW4oXCJcIik7XG4gIH07XG5cbiAgLy8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcbiAgbGlzdC5pID0gZnVuY3Rpb24gaShtb2R1bGVzLCBtZWRpYSwgZGVkdXBlLCBzdXBwb3J0cywgbGF5ZXIpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZXMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIG1vZHVsZXMgPSBbW251bGwsIG1vZHVsZXMsIHVuZGVmaW5lZF1dO1xuICAgIH1cbiAgICB2YXIgYWxyZWFkeUltcG9ydGVkTW9kdWxlcyA9IHt9O1xuICAgIGlmIChkZWR1cGUpIHtcbiAgICAgIGZvciAodmFyIGsgPSAwOyBrIDwgdGhpcy5sZW5ndGg7IGsrKykge1xuICAgICAgICB2YXIgaWQgPSB0aGlzW2tdWzBdO1xuICAgICAgICBpZiAoaWQgIT0gbnVsbCkge1xuICAgICAgICAgIGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKHZhciBfayA9IDA7IF9rIDwgbW9kdWxlcy5sZW5ndGg7IF9rKyspIHtcbiAgICAgIHZhciBpdGVtID0gW10uY29uY2F0KG1vZHVsZXNbX2tdKTtcbiAgICAgIGlmIChkZWR1cGUgJiYgYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpdGVtWzBdXSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbGF5ZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtWzVdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBsYXllclwiLmNvbmNhdChpdGVtWzVdLmxlbmd0aCA+IDAgPyBcIiBcIi5jb25jYXQoaXRlbVs1XSkgOiBcIlwiLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobWVkaWEpIHtcbiAgICAgICAgaWYgKCFpdGVtWzJdKSB7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBtZWRpYSBcIi5jb25jYXQoaXRlbVsyXSwgXCIge1wiKS5jb25jYXQoaXRlbVsxXSwgXCJ9XCIpO1xuICAgICAgICAgIGl0ZW1bMl0gPSBtZWRpYTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN1cHBvcnRzKSB7XG4gICAgICAgIGlmICghaXRlbVs0XSkge1xuICAgICAgICAgIGl0ZW1bNF0gPSBcIlwiLmNvbmNhdChzdXBwb3J0cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQHN1cHBvcnRzIChcIi5jb25jYXQoaXRlbVs0XSwgXCIpIHtcIikuY29uY2F0KGl0ZW1bMV0sIFwifVwiKTtcbiAgICAgICAgICBpdGVtWzRdID0gc3VwcG9ydHM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxpc3QucHVzaChpdGVtKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBsaXN0O1xufTsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///645\n')},537:module=>{"use strict";eval('\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === "function") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64);\n var sourceMapping = "/*# ".concat(data, " */");\n return [content].concat([sourceMapping]).join("\\n");\n }\n return [content].join("\\n");\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTM3LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsY0FBYztBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL3NvdXJjZU1hcHMuanM/YWYxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlbSkge1xuICB2YXIgY29udGVudCA9IGl0ZW1bMV07XG4gIHZhciBjc3NNYXBwaW5nID0gaXRlbVszXTtcbiAgaWYgKCFjc3NNYXBwaW5nKSB7XG4gICAgcmV0dXJuIGNvbnRlbnQ7XG4gIH1cbiAgaWYgKHR5cGVvZiBidG9hID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB2YXIgYmFzZTY0ID0gYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoY3NzTWFwcGluZykpKSk7XG4gICAgdmFyIGRhdGEgPSBcInNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LFwiLmNvbmNhdChiYXNlNjQpO1xuICAgIHZhciBzb3VyY2VNYXBwaW5nID0gXCIvKiMgXCIuY29uY2F0KGRhdGEsIFwiICovXCIpO1xuICAgIHJldHVybiBbY29udGVudF0uY29uY2F0KFtzb3VyY2VNYXBwaW5nXSkuam9pbihcIlxcblwiKTtcbiAgfVxuICByZXR1cm4gW2NvbnRlbnRdLmpvaW4oXCJcXG5cIik7XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///537\n')},543:(__unused_webpack_module,exports)=>{"use strict";eval("var __webpack_unused_export__;\n\n\n__webpack_unused_export__ = ({\n value: true\n});\nexports.Z = void 0;\nvar raf = function raf(callback) {\n return +setTimeout(callback, 16);\n};\nvar caf = function caf(num) {\n return clearTimeout(num);\n};\nif (typeof window !== 'undefined' && 'requestAnimationFrame' in window) {\n raf = function raf(callback) {\n return window.requestAnimationFrame(callback);\n };\n caf = function caf(handle) {\n return window.cancelAnimationFrame(handle);\n };\n}\nvar rafUUID = 0;\nvar rafIds = new Map();\nfunction cleanup(id) {\n rafIds.delete(id);\n}\nvar wrapperRaf = function wrapperRaf(callback) {\n var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n rafUUID += 1;\n var id = rafUUID;\n function callRef(leftTimes) {\n if (leftTimes === 0) {\n // Clean up\n cleanup(id);\n\n // Trigger\n callback();\n } else {\n // Next raf\n var realId = raf(function () {\n callRef(leftTimes - 1);\n });\n\n // Bind real raf id\n rafIds.set(id, realId);\n }\n }\n callRef(times);\n return id;\n};\nwrapperRaf.cancel = function (id) {\n var realId = rafIds.get(id);\n cleanup(realId);\n return caf(realId);\n};\nvar _default = wrapperRaf;\nexports.Z = _default;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTQzLmpzIiwibWFwcGluZ3MiOiI7QUFBYTs7QUFFYiw2QkFBNkM7QUFDN0M7QUFDQSxDQUFDLENBQUM7QUFDRixTQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmMtdXRpbC9saWIvcmFmLmpzPzZmOGQiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG52YXIgcmFmID0gZnVuY3Rpb24gcmFmKGNhbGxiYWNrKSB7XG4gIHJldHVybiArc2V0VGltZW91dChjYWxsYmFjaywgMTYpO1xufTtcbnZhciBjYWYgPSBmdW5jdGlvbiBjYWYobnVtKSB7XG4gIHJldHVybiBjbGVhclRpbWVvdXQobnVtKTtcbn07XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgJ3JlcXVlc3RBbmltYXRpb25GcmFtZScgaW4gd2luZG93KSB7XG4gIHJhZiA9IGZ1bmN0aW9uIHJhZihjYWxsYmFjaykge1xuICAgIHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGNhbGxiYWNrKTtcbiAgfTtcbiAgY2FmID0gZnVuY3Rpb24gY2FmKGhhbmRsZSkge1xuICAgIHJldHVybiB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoaGFuZGxlKTtcbiAgfTtcbn1cbnZhciByYWZVVUlEID0gMDtcbnZhciByYWZJZHMgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBjbGVhbnVwKGlkKSB7XG4gIHJhZklkcy5kZWxldGUoaWQpO1xufVxudmFyIHdyYXBwZXJSYWYgPSBmdW5jdGlvbiB3cmFwcGVyUmFmKGNhbGxiYWNrKSB7XG4gIHZhciB0aW1lcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDogMTtcbiAgcmFmVVVJRCArPSAxO1xuICB2YXIgaWQgPSByYWZVVUlEO1xuICBmdW5jdGlvbiBjYWxsUmVmKGxlZnRUaW1lcykge1xuICAgIGlmIChsZWZ0VGltZXMgPT09IDApIHtcbiAgICAgIC8vIENsZWFuIHVwXG4gICAgICBjbGVhbnVwKGlkKTtcblxuICAgICAgLy8gVHJpZ2dlclxuICAgICAgY2FsbGJhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTmV4dCByYWZcbiAgICAgIHZhciByZWFsSWQgPSByYWYoZnVuY3Rpb24gKCkge1xuICAgICAgICBjYWxsUmVmKGxlZnRUaW1lcyAtIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEJpbmQgcmVhbCByYWYgaWRcbiAgICAgIHJhZklkcy5zZXQoaWQsIHJlYWxJZCk7XG4gICAgfVxuICB9XG4gIGNhbGxSZWYodGltZXMpO1xuICByZXR1cm4gaWQ7XG59O1xud3JhcHBlclJhZi5jYW5jZWwgPSBmdW5jdGlvbiAoaWQpIHtcbiAgdmFyIHJlYWxJZCA9IHJhZklkcy5nZXQoaWQpO1xuICBjbGVhbnVwKHJlYWxJZCk7XG4gIHJldHVybiBjYWYocmVhbElkKTtcbn07XG52YXIgX2RlZmF1bHQgPSB3cmFwcGVyUmFmO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///543\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")},921:(__unused_webpack_module,exports)=>{"use strict";eval('var __webpack_unused_export__;\n/** @license React v16.13.1\n * react-is.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\nvar b="function"===typeof Symbol&&Symbol.for,c=b?Symbol.for("react.element"):60103,d=b?Symbol.for("react.portal"):60106,e=b?Symbol.for("react.fragment"):60107,f=b?Symbol.for("react.strict_mode"):60108,g=b?Symbol.for("react.profiler"):60114,h=b?Symbol.for("react.provider"):60109,k=b?Symbol.for("react.context"):60110,l=b?Symbol.for("react.async_mode"):60111,m=b?Symbol.for("react.concurrent_mode"):60111,n=b?Symbol.for("react.forward_ref"):60112,p=b?Symbol.for("react.suspense"):60113,q=b?\nSymbol.for("react.suspense_list"):60120,r=b?Symbol.for("react.memo"):60115,t=b?Symbol.for("react.lazy"):60116,v=b?Symbol.for("react.block"):60121,w=b?Symbol.for("react.fundamental"):60117,x=b?Symbol.for("react.responder"):60118,y=b?Symbol.for("react.scope"):60119;\nfunction z(a){if("object"===typeof a&&null!==a){var u=a.$$typeof;switch(u){case c:switch(a=a.type,a){case l:case m:case e:case g:case f:case p:return a;default:switch(a=a&&a.$$typeof,a){case k:case n:case t:case r:case h:return a;default:return u}}case d:return u}}}function A(a){return z(a)===m}__webpack_unused_export__=l;__webpack_unused_export__=m;__webpack_unused_export__=k;__webpack_unused_export__=h;__webpack_unused_export__=c;__webpack_unused_export__=n;__webpack_unused_export__=e;__webpack_unused_export__=t;__webpack_unused_export__=r;__webpack_unused_export__=d;\n__webpack_unused_export__=g;__webpack_unused_export__=f;__webpack_unused_export__=p;__webpack_unused_export__=function(a){return A(a)||z(a)===l};__webpack_unused_export__=A;__webpack_unused_export__=function(a){return z(a)===k};__webpack_unused_export__=function(a){return z(a)===h};__webpack_unused_export__=function(a){return"object"===typeof a&&null!==a&&a.$$typeof===c};__webpack_unused_export__=function(a){return z(a)===n};exports.isFragment=function(a){return z(a)===e};__webpack_unused_export__=function(a){return z(a)===t};\nexports.isMemo=function(a){return z(a)===r};__webpack_unused_export__=function(a){return z(a)===d};__webpack_unused_export__=function(a){return z(a)===g};__webpack_unused_export__=function(a){return z(a)===f};__webpack_unused_export__=function(a){return z(a)===p};\n__webpack_unused_export__=function(a){return"string"===typeof a||"function"===typeof a||a===e||a===m||a===g||a===f||a===p||a===q||"object"===typeof a&&null!==a&&(a.$$typeof===t||a.$$typeof===r||a.$$typeof===h||a.$$typeof===k||a.$$typeof===n||a.$$typeof===w||a.$$typeof===x||a.$$typeof===y||a.$$typeof===v)};__webpack_unused_export__=z;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTIxLmpzIiwibWFwcGluZ3MiOiI7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVhO0FBQ2I7QUFDQSxjQUFjLGtDQUFrQyxpQkFBaUIsVUFBVSwwQkFBMEIsbURBQW1ELGtDQUFrQyw0Q0FBNEMsa0JBQWtCLGtCQUFrQixjQUFjLGdCQUFnQix5QkFBaUIsR0FBRyx5QkFBc0IsR0FBRyx5QkFBdUIsR0FBRyx5QkFBdUIsR0FBRyx5QkFBZSxHQUFHLHlCQUFrQixHQUFHLHlCQUFnQixHQUFHLHlCQUFZLEdBQUcseUJBQVksR0FBRyx5QkFBYztBQUMvZSx5QkFBZ0IsR0FBRyx5QkFBa0IsR0FBRyx5QkFBZ0IsR0FBRyx5QkFBbUIsYUFBYSx1QkFBdUIseUJBQXdCLEdBQUcseUJBQXlCLGFBQWEsaUJBQWlCLHlCQUF5QixhQUFhLGlCQUFpQix5QkFBaUIsYUFBYSxxREFBcUQseUJBQW9CLGFBQWEsaUJBQWlCLGtCQUFrQixhQUFhLGlCQUFpQix5QkFBYyxhQUFhO0FBQzNjLGNBQWMsYUFBYSxpQkFBaUIseUJBQWdCLGFBQWEsaUJBQWlCLHlCQUFrQixhQUFhLGlCQUFpQix5QkFBb0IsYUFBYSxpQkFBaUIseUJBQWtCLGFBQWE7QUFDM04seUJBQTBCLGFBQWEsNlFBQTZRLHlCQUFjIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWlzL2Nqcy9yZWFjdC1pcy5wcm9kdWN0aW9uLm1pbi5qcz9hOTNkIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbGljZW5zZSBSZWFjdCB2MTYuMTMuMVxuICogcmVhY3QtaXMucHJvZHVjdGlvbi5taW4uanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7dmFyIGI9XCJmdW5jdGlvblwiPT09dHlwZW9mIFN5bWJvbCYmU3ltYm9sLmZvcixjPWI/U3ltYm9sLmZvcihcInJlYWN0LmVsZW1lbnRcIik6NjAxMDMsZD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5wb3J0YWxcIik6NjAxMDYsZT1iP1N5bWJvbC5mb3IoXCJyZWFjdC5mcmFnbWVudFwiKTo2MDEwNyxmPWI/U3ltYm9sLmZvcihcInJlYWN0LnN0cmljdF9tb2RlXCIpOjYwMTA4LGc9Yj9TeW1ib2wuZm9yKFwicmVhY3QucHJvZmlsZXJcIik6NjAxMTQsaD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5wcm92aWRlclwiKTo2MDEwOSxrPWI/U3ltYm9sLmZvcihcInJlYWN0LmNvbnRleHRcIik6NjAxMTAsbD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5hc3luY19tb2RlXCIpOjYwMTExLG09Yj9TeW1ib2wuZm9yKFwicmVhY3QuY29uY3VycmVudF9tb2RlXCIpOjYwMTExLG49Yj9TeW1ib2wuZm9yKFwicmVhY3QuZm9yd2FyZF9yZWZcIik6NjAxMTIscD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5zdXNwZW5zZVwiKTo2MDExMyxxPWI/XG5TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VfbGlzdFwiKTo2MDEyMCxyPWI/U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIik6NjAxMTUsdD1iP1N5bWJvbC5mb3IoXCJyZWFjdC5sYXp5XCIpOjYwMTE2LHY9Yj9TeW1ib2wuZm9yKFwicmVhY3QuYmxvY2tcIik6NjAxMjEsdz1iP1N5bWJvbC5mb3IoXCJyZWFjdC5mdW5kYW1lbnRhbFwiKTo2MDExNyx4PWI/U3ltYm9sLmZvcihcInJlYWN0LnJlc3BvbmRlclwiKTo2MDExOCx5PWI/U3ltYm9sLmZvcihcInJlYWN0LnNjb3BlXCIpOjYwMTE5O1xuZnVuY3Rpb24geihhKXtpZihcIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hKXt2YXIgdT1hLiQkdHlwZW9mO3N3aXRjaCh1KXtjYXNlIGM6c3dpdGNoKGE9YS50eXBlLGEpe2Nhc2UgbDpjYXNlIG06Y2FzZSBlOmNhc2UgZzpjYXNlIGY6Y2FzZSBwOnJldHVybiBhO2RlZmF1bHQ6c3dpdGNoKGE9YSYmYS4kJHR5cGVvZixhKXtjYXNlIGs6Y2FzZSBuOmNhc2UgdDpjYXNlIHI6Y2FzZSBoOnJldHVybiBhO2RlZmF1bHQ6cmV0dXJuIHV9fWNhc2UgZDpyZXR1cm4gdX19fWZ1bmN0aW9uIEEoYSl7cmV0dXJuIHooYSk9PT1tfWV4cG9ydHMuQXN5bmNNb2RlPWw7ZXhwb3J0cy5Db25jdXJyZW50TW9kZT1tO2V4cG9ydHMuQ29udGV4dENvbnN1bWVyPWs7ZXhwb3J0cy5Db250ZXh0UHJvdmlkZXI9aDtleHBvcnRzLkVsZW1lbnQ9YztleHBvcnRzLkZvcndhcmRSZWY9bjtleHBvcnRzLkZyYWdtZW50PWU7ZXhwb3J0cy5MYXp5PXQ7ZXhwb3J0cy5NZW1vPXI7ZXhwb3J0cy5Qb3J0YWw9ZDtcbmV4cG9ydHMuUHJvZmlsZXI9ZztleHBvcnRzLlN0cmljdE1vZGU9ZjtleHBvcnRzLlN1c3BlbnNlPXA7ZXhwb3J0cy5pc0FzeW5jTW9kZT1mdW5jdGlvbihhKXtyZXR1cm4gQShhKXx8eihhKT09PWx9O2V4cG9ydHMuaXNDb25jdXJyZW50TW9kZT1BO2V4cG9ydHMuaXNDb250ZXh0Q29uc3VtZXI9ZnVuY3Rpb24oYSl7cmV0dXJuIHooYSk9PT1rfTtleHBvcnRzLmlzQ29udGV4dFByb3ZpZGVyPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09aH07ZXhwb3J0cy5pc0VsZW1lbnQ9ZnVuY3Rpb24oYSl7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZudWxsIT09YSYmYS4kJHR5cGVvZj09PWN9O2V4cG9ydHMuaXNGb3J3YXJkUmVmPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09bn07ZXhwb3J0cy5pc0ZyYWdtZW50PWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09ZX07ZXhwb3J0cy5pc0xhenk9ZnVuY3Rpb24oYSl7cmV0dXJuIHooYSk9PT10fTtcbmV4cG9ydHMuaXNNZW1vPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09cn07ZXhwb3J0cy5pc1BvcnRhbD1mdW5jdGlvbihhKXtyZXR1cm4geihhKT09PWR9O2V4cG9ydHMuaXNQcm9maWxlcj1mdW5jdGlvbihhKXtyZXR1cm4geihhKT09PWd9O2V4cG9ydHMuaXNTdHJpY3RNb2RlPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09Zn07ZXhwb3J0cy5pc1N1c3BlbnNlPWZ1bmN0aW9uKGEpe3JldHVybiB6KGEpPT09cH07XG5leHBvcnRzLmlzVmFsaWRFbGVtZW50VHlwZT1mdW5jdGlvbihhKXtyZXR1cm5cInN0cmluZ1wiPT09dHlwZW9mIGF8fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBhfHxhPT09ZXx8YT09PW18fGE9PT1nfHxhPT09Znx8YT09PXB8fGE9PT1xfHxcIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hJiYoYS4kJHR5cGVvZj09PXR8fGEuJCR0eXBlb2Y9PT1yfHxhLiQkdHlwZW9mPT09aHx8YS4kJHR5cGVvZj09PWt8fGEuJCR0eXBlb2Y9PT1ufHxhLiQkdHlwZW9mPT09d3x8YS4kJHR5cGVvZj09PXh8fGEuJCR0eXBlb2Y9PT15fHxhLiQkdHlwZW9mPT09dil9O2V4cG9ydHMudHlwZU9mPXo7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///921\n')},864:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(921);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODY0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx5Q0FBNEQ7QUFDOUQsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QtaXMvaW5kZXguanM/NGNlYyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtaXMucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QtaXMuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///864\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")},379:module=>{"use strict";eval('\n\nvar stylesInDOM = [];\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n return result;\n}\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = "".concat(id, " ").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n identifiers.push(identifier);\n }\n return identifiers;\n}\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n return updater;\n}\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n var newLastIdentifiers = modulesToDom(newList, options);\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n var _index = getIndexByIdentifier(_identifier);\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n stylesInDOM.splice(_index, 1);\n }\n }\n lastIdentifiers = newLastIdentifiers;\n };\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzc5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQix3QkFBd0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsaUJBQWlCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsNEJBQTRCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsNkJBQTZCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzPzJkYmEiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBzdHlsZXNJbkRPTSA9IFtdO1xuZnVuY3Rpb24gZ2V0SW5kZXhCeUlkZW50aWZpZXIoaWRlbnRpZmllcikge1xuICB2YXIgcmVzdWx0ID0gLTE7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3R5bGVzSW5ET00ubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc3R5bGVzSW5ET01baV0uaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgcmVzdWx0ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbW9kdWxlc1RvRG9tKGxpc3QsIG9wdGlvbnMpIHtcbiAgdmFyIGlkQ291bnRNYXAgPSB7fTtcbiAgdmFyIGlkZW50aWZpZXJzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBpdGVtID0gbGlzdFtpXTtcbiAgICB2YXIgaWQgPSBvcHRpb25zLmJhc2UgPyBpdGVtWzBdICsgb3B0aW9ucy5iYXNlIDogaXRlbVswXTtcbiAgICB2YXIgY291bnQgPSBpZENvdW50TWFwW2lkXSB8fCAwO1xuICAgIHZhciBpZGVudGlmaWVyID0gXCJcIi5jb25jYXQoaWQsIFwiIFwiKS5jb25jYXQoY291bnQpO1xuICAgIGlkQ291bnRNYXBbaWRdID0gY291bnQgKyAxO1xuICAgIHZhciBpbmRleEJ5SWRlbnRpZmllciA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgIHZhciBvYmogPSB7XG4gICAgICBjc3M6IGl0ZW1bMV0sXG4gICAgICBtZWRpYTogaXRlbVsyXSxcbiAgICAgIHNvdXJjZU1hcDogaXRlbVszXSxcbiAgICAgIHN1cHBvcnRzOiBpdGVtWzRdLFxuICAgICAgbGF5ZXI6IGl0ZW1bNV1cbiAgICB9O1xuICAgIGlmIChpbmRleEJ5SWRlbnRpZmllciAhPT0gLTEpIHtcbiAgICAgIHN0eWxlc0luRE9NW2luZGV4QnlJZGVudGlmaWVyXS5yZWZlcmVuY2VzKys7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0udXBkYXRlcihvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXBkYXRlciA9IGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5ieUluZGV4ID0gaTtcbiAgICAgIHN0eWxlc0luRE9NLnNwbGljZShpLCAwLCB7XG4gICAgICAgIGlkZW50aWZpZXI6IGlkZW50aWZpZXIsXG4gICAgICAgIHVwZGF0ZXI6IHVwZGF0ZXIsXG4gICAgICAgIHJlZmVyZW5jZXM6IDFcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZGVudGlmaWVycy5wdXNoKGlkZW50aWZpZXIpO1xuICB9XG4gIHJldHVybiBpZGVudGlmaWVycztcbn1cbmZ1bmN0aW9uIGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpIHtcbiAgdmFyIGFwaSA9IG9wdGlvbnMuZG9tQVBJKG9wdGlvbnMpO1xuICBhcGkudXBkYXRlKG9iaik7XG4gIHZhciB1cGRhdGVyID0gZnVuY3Rpb24gdXBkYXRlcihuZXdPYmopIHtcbiAgICBpZiAobmV3T2JqKSB7XG4gICAgICBpZiAobmV3T2JqLmNzcyA9PT0gb2JqLmNzcyAmJiBuZXdPYmoubWVkaWEgPT09IG9iai5tZWRpYSAmJiBuZXdPYmouc291cmNlTWFwID09PSBvYmouc291cmNlTWFwICYmIG5ld09iai5zdXBwb3J0cyA9PT0gb2JqLnN1cHBvcnRzICYmIG5ld09iai5sYXllciA9PT0gb2JqLmxheWVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGFwaS51cGRhdGUob2JqID0gbmV3T2JqKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXBpLnJlbW92ZSgpO1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIHVwZGF0ZXI7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChsaXN0LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBsaXN0ID0gbGlzdCB8fCBbXTtcbiAgdmFyIGxhc3RJZGVudGlmaWVycyA9IG1vZHVsZXNUb0RvbShsaXN0LCBvcHRpb25zKTtcbiAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZShuZXdMaXN0KSB7XG4gICAgbmV3TGlzdCA9IG5ld0xpc3QgfHwgW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYXN0SWRlbnRpZmllcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBpZGVudGlmaWVyID0gbGFzdElkZW50aWZpZXJzW2ldO1xuICAgICAgdmFyIGluZGV4ID0gZ2V0SW5kZXhCeUlkZW50aWZpZXIoaWRlbnRpZmllcik7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleF0ucmVmZXJlbmNlcy0tO1xuICAgIH1cbiAgICB2YXIgbmV3TGFzdElkZW50aWZpZXJzID0gbW9kdWxlc1RvRG9tKG5ld0xpc3QsIG9wdGlvbnMpO1xuICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBsYXN0SWRlbnRpZmllcnMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICB2YXIgX2lkZW50aWZpZXIgPSBsYXN0SWRlbnRpZmllcnNbX2ldO1xuICAgICAgdmFyIF9pbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKF9pZGVudGlmaWVyKTtcbiAgICAgIGlmIChzdHlsZXNJbkRPTVtfaW5kZXhdLnJlZmVyZW5jZXMgPT09IDApIHtcbiAgICAgICAgc3R5bGVzSW5ET01bX2luZGV4XS51cGRhdGVyKCk7XG4gICAgICAgIHN0eWxlc0luRE9NLnNwbGljZShfaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBsYXN0SWRlbnRpZmllcnMgPSBuZXdMYXN0SWRlbnRpZmllcnM7XG4gIH07XG59OyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///379\n')},569:module=>{"use strict";eval('\n\nvar memo = {};\n\n/* istanbul ignore next */\nfunction getTarget(target) {\n if (typeof memo[target] === "undefined") {\n var styleTarget = document.querySelector(target);\n\n // Special case to return head of iframe instead of iframe itself\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n memo[target] = styleTarget;\n }\n return memo[target];\n}\n\n/* istanbul ignore next */\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n if (!target) {\n throw new Error("Couldn\'t find a style target. This probably means that the value for the \'insert\' parameter is invalid.");\n }\n target.appendChild(style);\n}\nmodule.exports = insertBySelector;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTY5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanM/YjIxNCJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpO1xuXG4gICAgLy8gU3BlY2lhbCBjYXNlIHRvIHJldHVybiBoZWFkIG9mIGlmcmFtZSBpbnN0ZWFkIG9mIGlmcmFtZSBpdHNlbGZcbiAgICBpZiAod2luZG93LkhUTUxJRnJhbWVFbGVtZW50ICYmIHN0eWxlVGFyZ2V0IGluc3RhbmNlb2Ygd2luZG93LkhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFjY2VzcyB0byBpZnJhbWUgaXMgYmxvY2tlZFxuICAgICAgICAvLyBkdWUgdG8gY3Jvc3Mtb3JpZ2luIHJlc3RyaWN0aW9uc1xuICAgICAgICBzdHlsZVRhcmdldCA9IHN0eWxlVGFyZ2V0LmNvbnRlbnREb2N1bWVudC5oZWFkO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvLyBpc3RhbmJ1bCBpZ25vcmUgbmV4dFxuICAgICAgICBzdHlsZVRhcmdldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG4gIHJldHVybiBtZW1vW3RhcmdldF07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gaW5zZXJ0QnlTZWxlY3RvcihpbnNlcnQsIHN0eWxlKSB7XG4gIHZhciB0YXJnZXQgPSBnZXRUYXJnZXQoaW5zZXJ0KTtcbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG4gIHRhcmdldC5hcHBlbmRDaGlsZChzdHlsZSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IGluc2VydEJ5U2VsZWN0b3I7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///569\n')},216:module=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement("style");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\nmodule.exports = insertStyleElement;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE2LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9pbnNlcnRTdHlsZUVsZW1lbnQuanM/ZGU2YyJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBpbnNlcnRTdHlsZUVsZW1lbnQob3B0aW9ucykge1xuICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzdHlsZVwiKTtcbiAgb3B0aW9ucy5zZXRBdHRyaWJ1dGVzKGVsZW1lbnQsIG9wdGlvbnMuYXR0cmlidXRlcyk7XG4gIG9wdGlvbnMuaW5zZXJ0KGVsZW1lbnQsIG9wdGlvbnMub3B0aW9ucyk7XG4gIHJldHVybiBlbGVtZW50O1xufVxubW9kdWxlLmV4cG9ydHMgPSBpbnNlcnRTdHlsZUVsZW1lbnQ7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///216\n')},565:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n if (nonce) {\n styleElement.setAttribute("nonce", nonce);\n }\n}\nmodule.exports = setAttributesWithoutAttributes;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTY1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQSxjQUFjLEtBQXdDLEdBQUcsc0JBQWlCLEdBQUcsQ0FBSTtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzP2RkY2UiXSwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzKHN0eWxlRWxlbWVudCkge1xuICB2YXIgbm9uY2UgPSB0eXBlb2YgX193ZWJwYWNrX25vbmNlX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3dlYnBhY2tfbm9uY2VfXyA6IG51bGw7XG4gIGlmIChub25jZSkge1xuICAgIHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBub25jZSk7XG4gIH1cbn1cbm1vZHVsZS5leHBvcnRzID0gc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///565\n')},795:module=>{"use strict";eval('\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = "";\n if (obj.supports) {\n css += "@supports (".concat(obj.supports, ") {");\n }\n if (obj.media) {\n css += "@media ".concat(obj.media, " {");\n }\n var needLayer = typeof obj.layer !== "undefined";\n if (needLayer) {\n css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {");\n }\n css += obj.css;\n if (needLayer) {\n css += "}";\n }\n if (obj.media) {\n css += "}";\n }\n if (obj.supports) {\n css += "}";\n }\n var sourceMap = obj.sourceMap;\n if (sourceMap && typeof btoa !== "undefined") {\n css += "\\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */");\n }\n\n // For old IE\n /* istanbul ignore if */\n options.styleTagTransform(css, styleElement, options.options);\n}\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n styleElement.parentNode.removeChild(styleElement);\n}\n\n/* istanbul ignore next */\nfunction domAPI(options) {\n if (typeof document === "undefined") {\n return {\n update: function update() {},\n remove: function remove() {}\n };\n }\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\nmodule.exports = domAPI;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzk1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xEO0FBQ0E7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBO0FBQ0EsaUZBQWlGO0FBQ2pGO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanM/ZTQ3OSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaikge1xuICB2YXIgY3NzID0gXCJcIjtcbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KG9iai5zdXBwb3J0cywgXCIpIHtcIik7XG4gIH1cbiAgaWYgKG9iai5tZWRpYSkge1xuICAgIGNzcyArPSBcIkBtZWRpYSBcIi5jb25jYXQob2JqLm1lZGlhLCBcIiB7XCIpO1xuICB9XG4gIHZhciBuZWVkTGF5ZXIgPSB0eXBlb2Ygb2JqLmxheWVyICE9PSBcInVuZGVmaW5lZFwiO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwiQGxheWVyXCIuY29uY2F0KG9iai5sYXllci5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KG9iai5sYXllcikgOiBcIlwiLCBcIiB7XCIpO1xuICB9XG4gIGNzcyArPSBvYmouY3NzO1xuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuICB2YXIgc291cmNlTWFwID0gb2JqLnNvdXJjZU1hcDtcbiAgaWYgKHNvdXJjZU1hcCAmJiB0eXBlb2YgYnRvYSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIuY29uY2F0KGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSksIFwiICovXCIpO1xuICB9XG5cbiAgLy8gRm9yIG9sZCBJRVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgICovXG4gIG9wdGlvbnMuc3R5bGVUYWdUcmFuc2Zvcm0oY3NzLCBzdHlsZUVsZW1lbnQsIG9wdGlvbnMub3B0aW9ucyk7XG59XG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KSB7XG4gIC8vIGlzdGFuYnVsIGlnbm9yZSBpZlxuICBpZiAoc3R5bGVFbGVtZW50LnBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3R5bGVFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50KTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBkb21BUEkob3B0aW9ucykge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKCkge30sXG4gICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHt9XG4gICAgfTtcbiAgfVxuICB2YXIgc3R5bGVFbGVtZW50ID0gb3B0aW9ucy5pbnNlcnRTdHlsZUVsZW1lbnQob3B0aW9ucyk7XG4gIHJldHVybiB7XG4gICAgdXBkYXRlOiBmdW5jdGlvbiB1cGRhdGUob2JqKSB7XG4gICAgICBhcHBseShzdHlsZUVsZW1lbnQsIG9wdGlvbnMsIG9iaik7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHtcbiAgICAgIHJlbW92ZVN0eWxlRWxlbWVudChzdHlsZUVsZW1lbnQpO1xuICAgIH1cbiAgfTtcbn1cbm1vZHVsZS5leHBvcnRzID0gZG9tQVBJOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///795\n')},589:module=>{"use strict";eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n styleElement.appendChild(document.createTextNode(css));\n }\n}\nmodule.exports = styleTagTransform;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTg5LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVUYWdUcmFuc2Zvcm0uanM/MWRkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5mdW5jdGlvbiBzdHlsZVRhZ1RyYW5zZm9ybShjc3MsIHN0eWxlRWxlbWVudCkge1xuICBpZiAoc3R5bGVFbGVtZW50LnN0eWxlU2hlZXQpIHtcbiAgICBzdHlsZUVsZW1lbnQuc3R5bGVTaGVldC5jc3NUZXh0ID0gY3NzO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChzdHlsZUVsZW1lbnQuZmlyc3RDaGlsZCkge1xuICAgICAgc3R5bGVFbGVtZW50LnJlbW92ZUNoaWxkKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKTtcbiAgICB9XG4gICAgc3R5bGVFbGVtZW50LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHN0eWxlVGFnVHJhbnNmb3JtOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///589\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__={},leafPrototypes,getProto;function __webpack_require__(I){var g=__webpack_module_cache__[I];if(void 0!==g)return g.exports;var n=__webpack_module_cache__[I]={id: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},getProto=Object.getPrototypeOf?I=>Object.getPrototypeOf(I):I=>I.__proto__,__webpack_require__.t=function(I,g){if(1&g&&(I=this(I)),8&g)return I;if("object"==typeof I&&I){if(4&g&&I.__esModule)return I;if(16&g&&"function"==typeof I.then)return I}var n=Object.create(null);__webpack_require__.r(n);var t={};leafPrototypes=leafPrototypes||[null,getProto({}),getProto([]),getProto(getProto)];for(var e=2&g&&I;"object"==typeof e&&!~leafPrototypes.indexOf(e);e=getProto(e))Object.getOwnPropertyNames(e).forEach((g=>t[g]=()=>I[g]));return t.default=()=>I,__webpack_require__.d(n,t),n},__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__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(I){if("object"==typeof window)return window}}(),__webpack_require__.o=(I,g)=>Object.prototype.hasOwnProperty.call(I,g),__webpack_require__.r=I=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(I,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(I,"__esModule",{value:!0})},__webpack_require__.nc=void 0;var __webpack_exports__=__webpack_require__(905)})();
\ No newline at end of file |
